【问题标题】:Web API refresh token not refreshing when access token is expired访问令牌过期时 Web API 刷新令牌不刷新
【发布时间】:2018-03-22 05:12:26
【问题描述】:

在我的 Web API 中,我正在实现基于 owin 持有者令牌的身份验证,在我的客户端应用程序中,我想在访问令牌过期时使用刷新令牌刷新访问令牌,这就是为什么我将访问令牌的到期时间设置为仅 15 分钟和将令牌刷新到 1 小时。当我的原始访问令牌过期时,我无法刷新访问令牌,即使我的刷新令牌一直有效,但在访问令牌有效时它工作正常。 下面是我的代码。

public override void Create(AuthenticationTokenCreateContext context)
        {
            Guid Token = Guid.NewGuid();
            using (InfoSystemEntities dbContext = new InfoSystemEntities())
            {
                RefreshToken RToken = new RefreshToken()
                {
                    Token = Token,
                    IssueDateUtc = DateTime.UtcNow,
                    ExpiryDateUtc = DateTime.UtcNow.AddMinutes(Params.RefreshPasswordExpiryInMinutes),
                    IssuedTo = context.Ticket.Identity.GetUserId<int>()
                };

                context.Ticket.Properties.IssuedUtc = RToken.IssueDateUtc;
                context.Ticket.Properties.IssuedUtc = RToken.ExpiryDateUtc;

                RToken.ProtectedTicket = context.SerializeTicket();
                dbContext.RefreshTokens.Add(RToken);

                if (dbContext.SaveChanges() > 0)
                {
                    context.SetToken(Token.ToString());
                    //context.SetToken(context.SerializeTicket());
                }
            }
        }

        public override void Receive(AuthenticationTokenReceiveContext context)
        {
            using (InfoSystemEntities dbContext = new InfoSystemEntities())
            {
                Guid Token = Guid.Parse(context.Token);
                RefreshToken RToken = dbContext.RefreshTokens.Where(T => T.Token == Token).FirstOrDefault();

                if (RToken != null)
                {
                    if (RToken.ExpiryDateUtc > DateTime.UtcNow)
                    {
                        context.DeserializeTicket(RToken.ProtectedTicket);
                    }
                    else
                    {
                        context.Response.Write("refresh_token not found or expired");
                    }

                    //dbContext.RefreshTokens.Attach(RToken);
                    //dbContext.RefreshTokens.Remove(RToken);
                    //dbContext.SaveChanges();
                }
                else
                {
                    context.Response.Write("refresh_token not found or expired");
                }
            }
        }

public class OAuthProvider : OAuthAuthorizationServerProvider
    {
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            //context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
            //MyUserManager CustomUserManager = HttpContext.Current.GetOwinContext().GetUserManager<MyUserManager>();
            MyUserManager CustomUserManager = new MyUserManager();

            var user = await CustomUserManager.FindAsync(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                context.Rejected();
                return;
            }

            if (!user.IsActive)
            {
                context.SetError("invalid_grant", "The user account is disabled");
                context.Rejected();
                return;
            }

            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()));
            identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            identity.AddClaim(new Claim("FullName", user.FirstName + " " + user.LastName));
            // Optional : You can add a role based claim by uncommenting the line below.
            identity.AddClaim(new Claim("Role", user.Role));
            identity.AddClaim(new Claim(ClaimTypes.Role, user.Role));

            var props = new AuthenticationProperties(new Dictionary<string, string> { { "firstname", user.FirstName }, { "lastname", user.LastName }, { "email", user.UserName }, { "role", user.Role }, { "refresh_token_expires_in", (Params.RefreshPasswordExpiryInMinutes * 60).ToString() } });

            var ticket = new AuthenticationTicket(identity, props);

            context.Validated(ticket);
        }


        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            if (context.ClientId == null)
                context.Validated();

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

        public override Task TokenEndpoint(OAuthTokenEndpointContext context)
        {
            foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
            {
                context.AdditionalResponseParameters.Add(property.Key, property.Value);
            }

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

        public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
        {
            var newIdentity = new ClaimsIdentity(context.Ticket.Identity);
            newIdentity.AddClaim(new Claim("newClaim", "newValue"));

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

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

【问题讨论】:

  • 检查你的代码 context.Ticket.Properties.IssuedUtc = RToken.ExpiryDateUtc;应该是 ExpiresUtc 而不是 IssuedUtc
  • @SunilShrestha,谢谢兄弟,我太傻了,我浪费了太多时间来找出问题,你可以在下面写下你的答案,这样我就可以接受了:)
  • 好的,谢谢,很高兴

标签: oauth-2.0 asp.net-web-api2 owin refresh-token


【解决方案1】:

在 context.Ticket.Properties.IssuedUtc = RToken.ExpiryDateUtc 中检查您的代码;应该是 ExpiresUtc 而不是 IssuedUtc

【讨论】:

    猜你喜欢
    • 2019-08-05
    • 2019-04-07
    • 2018-06-05
    • 2021-12-19
    • 2019-05-31
    • 2021-11-16
    • 2021-08-25
    • 2022-10-31
    • 2019-06-29
    相关资源
    最近更新 更多