asp.netoauthoauth-2.0asp.net-web-apiowin

OAuth2 WebApi Token Expiration


I am trying to set a token expiration time dynamically, but it appears it just keeps defaulting to 20 minutes.

Here is my ConfigureAuth:

public void ConfigureAuth(IAppBuilder app)
{

        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(""),
            // In production mode set AllowInsecureHttp = false
            AllowInsecureHttp = true
        };

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

}

Here is my GrantResourceOwnerCredentials method:

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {

        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

        var hasValidLogin = (new login().authenticate(context.UserName, context.Password, "") == "valid");

        if (hasValidLogin == false)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return Task.FromResult<object>(null);
        }

        var oAuthIdentity = CreateIdentity(context);
        var oAuthProperties = CreateProperties(context);

        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, oAuthProperties);

        context.Validated(ticket);
        return Task.FromResult<object>(null);
    }

And here is my SetProperties method where I can setting the expiration:

    public static AuthenticationProperties CreateProperties(OAuthGrantResourceOwnerCredentialsContext context)
    {

        IDictionary<string, string> data = new Dictionary<string, string>
        {
            { "client_id", context.ClientId }
        };

        var response = new AuthenticationProperties(data);
        response.ExpiresUtc = DateTime.Now.AddMonths(1);

        return response;
    }

Even after that, the token is returning:

{
  "access_token": ".....",
  "token_type": "bearer",
  "expires_in": 1199,
  "client_id": ".....",
  ".expires": "Fri, 13 Nov 2015 20:24:06 GMT",
  ".issued": "Fri, 13 Nov 2015 20:04:06 GMT"
}

Any ideas why I cannot set the expiration where I currently am? This server will take a variety of different clients with different specified expiration times, therefore I figured this is the place to do this. Is there somewhere else that I should doing this at? Thanks!


Solution

  • The behavior you're seeing is directly caused by the fact the OAuth2 authorization server always discards your own expiration when you set it in the GrantResourceOwnerCredentials notification (the other Grant* notifications are also impacted): https://github.com/aspnet/AspNetKatana/blob/e03c3dbb958b/src/Microsoft.Owin.Security.OAuth/OAuthAuthorizationServerHandler.cs#L387

    A work around is to set the expiration date in AuthenticationTokenProvider.CreateAsync (the class you use for OAuthAuthorizationServerOptions.AccessTokenProvider):

    Simply set context.Ticket.Properties.ExpiresUtc with the expiration date of your choice, and it should work as intented:

    public class AccessTokenProvider : AuthenticationTokenProvider
    {
        public override void Create(AuthenticationTokenCreateContext context)
        {
            context.Ticket.Properties.ExpiresUtc = // set the appropriate expiration date.
    
            context.SetToken(context.SerializeTicket());
        }
    }
    

    You can also take a look at AspNet.Security.OpenIdConnect.Server, a fork of the OAuth2 authorization server offered by OWIN/Katana that natively supports setting the expiration date from GrantResourceOwnerCredentials: https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tree/dev