asp.net-web-apioauthtokenowin

Implementing a dynamic OAuthBearerServerOptions AccessTokenExpireTimeSpan value from data store


The context of this post involves ASP.NET Web API 2.2 + OWIN The environment is a single application with both OWIN server and Web Api.

Background:

In the Startup class, one must specify OAuthBearerServerOptions which is supplied to the OAuthBearerAuthenticationProvider. These options are created during the start up of the OWIN server. On the OAuthBearerServerOptions, I must specify the AccessTokenExpireTimeSpan so that I can ensure expiry of tokens.

The Issue

I must be able to dynamically specify the Expiration time span on a per authentication request basis. I am unsure if this can be done and was wondering:

Content of start up config:

    var config = new HttpConfiguration();

    WebApiConfig.Register(config);


    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

    var OAuthServerOptions = new OAuthAuthorizationServerOptions()
    {
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString("/OAuth"),
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(**THIS NEEDS TO BE DYNAMIC**)),
        Provider = new AuthorizationServerProvider()
    };

    //STOP!!!!!!!!
    //DO NOT CHANGE THE ORDER OF THE BELOW app.Use statements!!!!!

    //Token Generation 
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); //this MUST come before oauth registration
    app.UseOAuthAuthorizationServer(OAuthServerOptions);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
    {
        Provider = new BearerProvider()
    });
    app.UseAutofacMiddleware(container); //this MUST come before UseAutofacWebApi
    app.UseAutofacWebApi(config);//this MUST come before app.UseWebApi
    app.UseWebApi(config);

I started messing with the BearerProvider class (see app.UseOAuthBearerAuthentication above for where I use this class) and in specific, the ValidateIdentity method, but wasn't sure if that was the proper point in the auth workflow to set this value. It seemed appropriate, but I seek validation of my position.

public class BearerProvider : OAuthBearerAuthenticationProvider
{
    public override async Task RequestToken(OAuthRequestTokenContext context)
    {
        await base.RequestToken(context);

        //No token? attempt to retrieve from query string
        if (String.IsNullOrEmpty(context.Token))
        {
            context.Token = context.Request.Query.Get("access_token");

        }
    }
    public override Task ValidateIdentity(OAuthValidateIdentityContext context)
    {
        //context.Ticket.Properties.ExpiresUtc= //SOME DB CALL TO FIND OUT EXPIRE VALUE..IS THIS PROPER?
        return base.ValidateIdentity(context);
    }
}

Thanks in advance!


Solution

  • Setting context.Options.AccessTokenExpireTimeSpan will actually change the global value, and affect all requests, that won't work for the original requirement.

    The right place is the TokenEndpoint method.

    public override Task TokenEndpoint(OAuthTokenEndpointContext context)
    {
        ...
    
        if (someCondition)
        {
            context.Properties.ExpiresUtc = GetExpirationDateFromDB();
        }
    
        ...
    }