首页 > 解决方案 > Microsoft Owin 令牌和刷新令牌即将到期

问题描述

我正在使用 WebAPI 来回答 android 和我的 angular UI 请求。出于身份验证目的,我使用了 OWIN 库。我已将令牌到期时间设置为 1 天并将刷新令牌到期时间设置为 7 天,但我的令牌在 2 小时后到期,并且当我调用刷新令牌函数时收到 invalid_grant 响应...

有谁知道为什么这个过期时间不起作用?

这是我的代码:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var corsPolicy = new EnableCorsAttribute("*", "*", "*");
        app.UseCors(new CorsOptions
        {
            PolicyProvider = new CorsPolicyProvider
            {
                PolicyResolver = request =>
                    request.Path.Value == "/token" ?
                        corsPolicy.GetCorsPolicyAsync(null, CancellationToken.None) :
                        Task.FromResult<CorsPolicy>(null)
            }
        });

        OAuthAuthorizationServerOptions option = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/token"),
            Provider = new ApplicationOAuthProvider(),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            AllowInsecureHttp = true,
            RefreshTokenProvider = new ApplicationRefreshTokenProvider()
        };
        app.UseOAuthBearerTokens(option);
        app.UseOAuthAuthorizationServer(option);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }
}

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

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

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        UserCredential uc = Repository.UserRepository.FindByUserNameAndPassword(context.UserName, context.Password);

        if (uc != null)
        {
            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            identity.AddClaim(new Claim("Username", uc.UserName));
            identity.AddClaim(new Claim("Id", uc.User.Id.ToString()));
            identity.AddClaim(new Claim("Phone", uc.User.Phone));
            identity.AddClaim(new Claim("FirstName", uc.User.FirstName));
            identity.AddClaim(new Claim("LastName", uc.User.LastName));
            identity.AddClaim(new Claim("Address", uc.User.Address));
            identity.AddClaim(new Claim("PostalCode", uc.User.PostalCode));
            identity.AddClaim(new Claim("LoggedOn", DateTime.Now.ToString()));
            identity.AddClaim(new Claim(ClaimTypes.Role, uc.User.Role));
            var additionalData = new AuthenticationProperties(new Dictionary<string, string>
            {
                {
                    "role", uc.User.Role
                }
            });
            var token = new AuthenticationTicket(identity, additionalData);
            context.Validated(token);
        }
        else
        {
            context.SetError("invalid_grant", "Username or password is not valid.");
            context.Rejected();
        }

    }

    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);

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

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

public class ApplicationRefreshTokenProvider : IAuthenticationTokenProvider
{
    private const int EXPIRE_DAYS = 7;

    public async Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        Create(context);
    }

    public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
    {
        Receive(context);
    }

    public void Create(AuthenticationTokenCreateContext context)
    {
        object inputs;
        context.OwinContext.Environment.TryGetValue("Microsoft.Owin.Form#collection", out inputs);

        var grantType = ((FormCollection)inputs)?.GetValues("grant_type");

        var grant = grantType.FirstOrDefault();

        if (grant == null || grant.Equals("refresh_token")) return;

        context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(EXPIRE_DAYS);

        context.SetToken(context.SerializeTicket());
    }

    public void Receive(AuthenticationTokenReceiveContext context)
    {
        context.DeserializeTicket(context.Token);

        if (context.Ticket == null)
        {
            context.Response.StatusCode = 400;
            context.Response.ContentType = "application/json";
            context.Response.ReasonPhrase = "invalid token";
            return;
        }

        if (context.Ticket.Properties.ExpiresUtc <= DateTime.UtcNow)
        {
            context.Response.StatusCode = 401;
            context.Response.ContentType = "application/json";
            context.Response.ReasonPhrase = "unauthorized";
            return;
        }

        context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(EXPIRE_DAYS);
        context.SetTicket(context.Ticket);
    }
}

我做什么: 我首先发送一个令牌请求并获得一个令牌和一个刷新令牌。大约 2 小时后,当我发送 refresh_token 请求时,我收到 invalid_grant 响应,尽管令牌有效期设置为 1 天!!!

标签: asp.net-web-apirefresh-tokenowin-middleware

解决方案


推荐阅读