Phuong Nguyen
Phuong Nguyen

Reputation: 3070

OWIN Oauth differentiate expired and invalid token

I use OWIN Oauth in my ASP.NET MVC application to provide access token for mobile applications. Here's the setup of OAuth:

        app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/api/authenticate/login"),
            Provider = dependencyContainer.GetService<IOAuthAuthorizationServerProvider>(),
            RefreshTokenProvider = dependencyContainer.GetService<IAuthenticationTokenProvider>(),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(applicationSettings.AccessTokenLifeTimeInMinutes),
            AllowInsecureHttp = true
        });

        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

I also have custom provider and custom refresh token provider as you can see above. Everything is working fine, when a request from mobile is expired or invalid, I use a custom AuthorizeAttribute to return a json with message "unauthorized"

public class ApiAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new JsonResult
        {
            Data = new
            {
                success = false,
                error = "Unauthorized"
            },
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };
    }
}

However in one scenario, the mobile applications need to differentiate the response from server for 2 cases: access token is expired, or access token is invalid (.e.g. modified in the middle). I'm not sure how I can implement that requirement. I tried to create a custom access token provider, inheriting from AuthenticationTokenProvider, register it in UseOAuthAuthorizationServer() above, but both Receive() and ReceiveAsync() are not called when server receives access token from mobile

Upvotes: 0

Views: 1534

Answers (1)

Phuong Nguyen
Phuong Nguyen

Reputation: 3070

Solved the issue. My approach of creating custom access token provider works. Initially I registered it with UseOAuthAuthorizationServer(), but it should be registered using UseOAuthBearerAuthentication() instead

Here's my custom class, in case anyone needs:

public class CustomAccessTokenProvider : AuthenticationTokenProvider
{
    public override void Receive(AuthenticationTokenReceiveContext context)
    {
        context.DeserializeTicket(context.Token);
        var expired = context.Ticket.Properties.ExpiresUtc < DateTime.UtcNow;
        if (expired)
        {
            //If current token is expired, set a custom response header
            context.Response.Headers.Add("X-AccessTokenExpired", new string[] { "1" });
        }

        base.Receive(context);
    }
}

Register it when setting up OWIN OAuth:

app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
            {
                AccessTokenProvider = new CustomAccessTokenProvider()
            });

Upvotes: 3

Related Questions