Search code examples
asp.net-mvcauthenticationasp.net-web-apiowinrestful-authentication

How i can store bearer tokens on server-side and after validate how to delete on logout in Web API 2?


I am creating web api project, by default it have account controller in which i found Register,Logout and other api's . Using Web API 2, OAuth and OWIN

By /token i generated bearer token and his expiry time which is storing in OWIN Cookie authentication.

My Question is : -

  • how i can delete this token when user logout because after using logout service i can still call list data which is decorated with [Authorize]
  • can i store it in database and validate it, delete it when user logout

Logout code is below

    // POST api/Account/Logout
    [Route("Logout")]
    public IHttpActionResult Logout()
    {
        // Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
return ok();

}

and my /token code is below

 public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // Configure the application for OAuth based flow
        PublicClientId = "self";
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            // In production mode set AllowInsecureHttp = false
            AllowInsecureHttp = true
        };

}


Solution

  • You cannot delete the token in server, however you can forget the token in client side. Or you can create refresh token service

    Just create the class

    public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider {
            private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();
            public async Task CreateAsync(AuthenticationTokenCreateContext context) {
                var guid = Guid.NewGuid().ToString();
                _refreshTokens.TryAdd(guid, context.Ticket);
               context.SetToken(guid);
            }
    
            public async Task ReceiveAsync(AuthenticationTokenReceiveContext context) {
                AuthenticationTicket ticket;
                if (_refreshTokens.TryRemove(context.Token, out ticket)) {
                    context.SetTicket(ticket);
                }
            } 
        }
    

    Register it in

    static Startup() {
                OAuthOptions = new OAuthAuthorizationServerOptions {
                    TokenEndpointPath = new PathString("/api/Login"),
                    Provider = new OAuthProvider(),
                    RefreshTokenProvider = new SimpleRefreshTokenProvider(),
                    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),
                    AllowInsecureHttp = true,
                };
            }
    

    Override OAuthAuthorizationServerProvider

    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) {       
            if (context.TryGetBasicCredentials(out clientId, out clientSecret)) {
                if (clientSecret == "secret") {
                    context.OwinContext.Set<string>("as:client_id", clientId);
                    context.Validated();
                }
            }
        return Task.FromResult<object>(null);
    

    }

    and your service request should be look like this

    Authorization: Basic Y2xpZW50MTpzZWNyZXQ=
    Content-Type: application/x-www-form-urlencoded
    
    username=care%40agentExperience.com&password=test&client_id=client1&clientSecret=secret&grant_type=refresh_token