Saturday, March 28, 2015

Implementing Refresh Tokens using OAuth2, OWIN and ASP.NET Web API

If you want to implement Refresh Tokens in your OWIN application with OAuth2, searching for how to accomplish this is not the easiest thing to find on the web.

Fortunately, Dominick Baier comes to the rescue regarding this topic: http://leastprivilege.com/2013/11/15/adding-refresh-tokens-to-a-web-api-v2-authorization-server/

This thread provides a much simpler solution to Dominick Baier's implementation of Refresh Tokens, but may not meet all of your needs and does not address overriding the GrantRefreshToken method in the
OAuthAuthorizationServerProvider class:  http://stackoverflow.com/questions/20637674/owin-security-how-to-implement-oauth2-refresh-tokens

However, when I implemented the 2 solutions in conjunction with the solution provided by Scott Allen: http://odetocode.com/blogs/scott/archive/2015/01/15/using-json-web-tokens-with-katana-and-webapi.aspx

I ended up with the following results when using the Stack Overflow solution:





As you can from the screenshot above in Fiddler, I am getting a Refresh Token back as expected.

However, when implementing Dominick Baier's solution, I got the following result:


Instead of getting the Refresh Token back as expected, I obtained an as:client_id value back.  Therefore, the code sample as posted in the article does not present a complete solution and is probably dependent on many other aspects in the solution to get everything working as expected.  You can get the full source code for Dominick Baier's solution here: https://github.com/IdentityModel/Thinktecture.IdentityModel/tree/master/samples/OAuth2/EmbeddedResourceOwnerFlowWithRefreshTokens

For your convenience, I have provided the a variation of the code from the Stack Overflow article as well as Scott Allen’s code here:
public class ApplicationRefreshTokenProvider : AuthenticationTokenProvider

{

 

    private int _tokenExpiration;

 

    public ApplicationRefreshTokenProvider()

    {

        _tokenExpiration = Convert.ToInt32(ConfigurationManager.AppSettings["TokenExpiration"]);

    }

    public override void Create(AuthenticationTokenCreateContext context)

    {

        // Expiration time in seconds

        int expire = _tokenExpiration;

        context.Ticket.Properties.ExpiresUtc = new DateTimeOffset(DateTime.Now.AddMinutes(expire));

        context.SetToken(context.SerializeTicket());

    }

 

    public override void Receive(AuthenticationTokenReceiveContext context)

    {

        context.DeserializeTicket(context.Token);

    }

 

}



OAuthOptions = new OAuthAuthorizationServerOptions

{

    TokenEndpointPath = new PathString("/Token"),

    Provider = new ApplicationOAuthProvider(),

    AccessTokenFormat = new MyJwtFormat(),

    RefreshTokenProvider = new ApplicationRefreshTokenProvider(),

    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(tokenExpiration),

    AllowInsecureHttp = true

};

1 comment:

  1. Great post! I was searching the whole web for something like this. Simple :-) Thanks!

    ReplyDelete