Asp.Net Web API 2 Customize Token Expiration

Problem Statement: We need our Web API  to issue bearer tokens with different expiration based on type of the client (Web, Mobile and Desktop).

Solution 1: Let the WEB API always issue token with same expiration for every client. this is straight forward implementation done in application startup.

AccessTokenExpireTimeSpan: you can set this property based on the security needs of your application.


OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(PublicClientId),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(2),
                //TODO
                // In production mode set AllowInsecureHttp = false
                AllowInsecureHttp = true,
                AuthenticationMode = AuthenticationMode.Active,
                AuthenticationType = OAuthDefaults.AuthenticationType
            };

// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);

Solution 2: Let the Web API issue token with different expiration times based on the client type. we would give longer expiration for desktop clients.

OAuthAuthorizationServerOptions:
Provider: we have custom implementation for the ApplicationOAuthProvider as shown in Solution 1. Now for each client id we can set different expiration.
AccessTokenExpireTimeSpan: You need to comment this in start up configuration as shown in solution becuase you are customizing it in provider class.

Note: I didn’t provide full implementation here.


public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        string clientId;
        string clientSecret;
        //This AuthModel is my custom model that will be passed in OwinContext
        var authModel = new AuthModel();

        if (context.TryGetFormCredentials(out clientId, out clientSecret))
        {
            if (clientId.Equals("appWeb", StringComparison.OrdinalIgnoreCase))
            {
                context.Options.AccessTokenExpireTimeSpan = TimeSpan.FromHours(2);

                context.OwinContext.Set("oauth:client", authModel);
                context.Validated(clientId);// please validate client credentials.
            }
            else if (clientId.Equals("mobile", StringComparison.OrdinalIgnoreCase))
            {
                context.Options.AccessTokenExpireTimeSpan = TimeSpan.FromDays(3);
                authModel.ClientSecret = clientSecret;

                context.OwinContext.Set("oauth:client", authModel);
                context.Validated(clientId); // please validate client credentials.
            }
            else
            {
                context.SetError("invalid_client", "Client credentials are invalid.");
                context.Rejected();
            }
        }
        else
        {
            context.SetError("invalid_client", "Client credentials are invalid.");
            context.Rejected();
        }

        return Task.FromResult(0);
    }
}

Happy Coding!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s