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!