OAuth Refresh Token does not deserialize / invalid

2019-06-12 16:31发布

I have followed the wonderful tutorial by Taiser Joudah for implementing refresh tokens with Asp.Net Web Api 2 and Owin. It all went so well...except I can't get it to work. :-) It all "seems" like it works up until the point I request a refresh token. Then all I get back is:

“error”: “invalid_grant”

and no description to go with. One of the comments on that post had the same symptom and the response was to generate a MachineKey for the web.config. I tried this but it didn't help. And I'm thinking that maybe only applies when the Auth and Resource server are not the same anyway, which in this case they are.

The bottom line is using PostMan I can make the request for the refresh token and in ReceiveAsync the context.Ticket deserialization does not work. After the call to “context.DeserializeTicket(refreshToken.ProtectedTicket);” the context.Ticket is still null. Curiously if I manually deserialize the ProtectedTicket using the Acccess Token’s AccessTokenFormat it will deserialize properly. But it does not work using the Refresh Token's RefreshTokenFormat object:

var thisWorks = Startup.OAuthOptions.AccessTokenFormat.Unprotect(refreshToken.ProtectedTicket);
var thisDoesnt = Startup.OAuthOptions.RefreshTokenFormat.Unprotect(refreshToken.ProtectedTicket);

It sure seems like a config problem…but I’ve racked my brains and compared a lot of samples. What could be causing this?

EDIT Oops...meant to link to the tutorial article: http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/

2条回答
狗以群分
2楼-- · 2019-06-12 16:39

I think your problem is the order you create the refresh_token with CreateAsync. Make sure you follow order bellow:

context.Ticket.Properties.IssuedUtc = refreshTokenProperties.IssuedUtc;
context.Ticket.Properties.ExpiresUtc = refreshTokenProperties.ExpiresUtc;
context.SetToken(context.SerializeTicket());

Then you can persist the token into DB. But have in mind that it is not necessary to persist. You can DeserializeTicket from context.Token in ReceiveAsync:

public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
    context.DeserializeTicket(context.Token);
    if (context.Ticket != null)
    {            
        context.SetTicket(context.Ticket);            
    }            
}

Hope this help!

查看更多
迷人小祖宗
3楼-- · 2019-06-12 16:46

Following the same tutorial, I had the same problem, this worked for me

public async Task CreateAsync(AuthenticationTokenCreateContext context)
{
    //...
    context.Ticket.Properties.AllowRefresh = true;

    token.ProtectedTicket = context.SerializeTicket();
    //...
}
查看更多
登录 后发表回答