Why GrantRefreshToken method is not called - Oauth2 ASP.NET Web API

Viewed 805

I send request to oauth2 server with request body :

grant_type=refresh_token&refresh_token=abc

I save refresh_token in database.

ReceiveAsync method :

public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
        {
            var allowedOrigin = context.OwinContext.Get<string>("clientAllowedOrigin");
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
            string hashTokenName = Helper.GetHash(context.Token);
            var refreshToken = await repo.FindRefreshToken(hashTokenName);
            if (refreshToken != null)
            {
                //Get protectedTicket from refreshToken class
                context.DeserializeTicket(refreshToken.ProtectedTicket);
                var result = await repo.RemoveRefreshToken(hashTokenName);
            }
        }

GrantRefreshToken method :

public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
        {
            var originClient = context.Ticket.Properties.Dictionary["client_id"];
            var currenClient = context.ClientId;
            if (originClient != currenClient)
            {
                context.SetError("Error");
                return Task.FromResult<object>(null);
            }
            var newIdentity = new ClaimsIdentity(context.Ticket.Identity);
            newIdentity.AddClaim(new Claim(ClaimTypes.Name, context.ClientId));

            var newTicket = new AuthenticationTicket(newIdentity, context.Ticket.Properties);
            context.Validated(newTicket);

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

Why GrantRefreshToken is not called when ReceiveAsync finished ?

3 Answers

I had been facing the same problem for two days.

the issue causes by ReceiveAsync method does not set OAuthGrantRefreshTokenContext context.ticket properly.

to diagnose that, use postman to send the refresh_token request. an invalid_grant error will be prompted. postman screenshot

the minimum requirement for generate a ticket is to set IssuedUtc & ExpiresUtc and leave other properties to default.

the code below can simply replicate the issue.

public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {

        AuthenticationTicket ticket = null;
        var identity = new ClaimsIdentity();
        var props = new AuthenticationProperties();
        ticket = new AuthenticationTicket(identity, props);
        context.SetTicket(ticket);
        //context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;
        //context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow;
    }

code result screen shot

once IssuedUtc & ExpiresUtc are set, GrantRefreshToken will be invoked.

enter image description here

solution: put a breakpoint by the end of ReceiveAsync method, check whether context.ticket is set properly. IssuedUtc & ExpiresUtc these two properties can not be null.

ReceiveAsync signature should be: public Task ReceiveAsync(AuthenticationTokenReceiveContext context)

And you should return a Task in that method.

I've faced the exact same problem, and the root cause in my case was the machine key, the engine use the machine key in serializing the ticket, so if you don't configure the machine key in web.config then one key could be used in the serialization process and another one in the deserialization. So try to configure the machine key in the web.cofig. Hope this helps

Related