【问题标题】:ASP.NET Core MVC JWT expires too earlyASP.NET Core MVC JWT 过早过期
【发布时间】:2018-05-02 01:09:28
【问题描述】:

我正在开发 mob 应用后端,并且正在使用 JWT。我的问题是它提前到期,我想我设置了 365 天。我在VS2015中使用asp.net core mvc v1。

这是我的 JWT 身份验证配置。该方法是从 Startup 类中调用的。

private void ConfigureAuth(IApplicationBuilder app)
    {
        secretKey = Guid.NewGuid().ToString();

        var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));

    app.UseSimpleTokenProvider(new TokenProviderOptions
    {
        Path = "/api/token",
        Audience = Audience,
        Issuer = Issuer,
        SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
        IdentityResolver = GetIdentity,
    });

    var tokenValidationParameters = new TokenValidationParameters
    {
        // The signing key must match!
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = signingKey,

        // Validate the JWT Issuer (iss) claim
        ValidateIssuer = true,
        ValidIssuer = Issuer,

        // Validate the JWT Audience (aud) claim
        ValidateAudience = true,
        ValidAudience = Audience,

        // Validate the token expiry
        ValidateLifetime = true,

        // If you want to allow a certain amount of clock drift, set that here:
        ClockSkew = TimeSpan.Zero
    };

    app.UseJwtBearerAuthentication(new JwtBearerOptions
    {
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        TokenValidationParameters = tokenValidationParameters
    });

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        AuthenticationScheme = "Cookie",
        CookieName = "access_token",
        TicketDataFormat = new CustomJwtDataFormat(SecurityAlgorithms.HmacSha256, tokenValidationParameters),
        Events = new CustomCookieAuthenticationEvents()
    });
}

private Task<ClaimsIdentity> GetIdentity(string email)
{
    ServiceMessage<UserEntity> request = _userService.FindByEmailAsync(email).Result;

    if (request != null && request.Success && request.ResultObject != null)
    {
        return Task.FromResult(CreateClaimsIdentity(request.ResultObject, "Token"));
    }

    // Credentials are invalid, or account doesn't exist
    return Task.FromResult<ClaimsIdentity>(null);
}

private ClaimsIdentity CreateClaimsIdentity(UserEntity user, string authenticationType)
{
    List<Claim> claimCollection = new List<Claim>
    {
        new Claim(ClaimTypes.NameIdentifier, user.Email, ClaimValueTypes.String),
        new Claim(ClaimTypes.Role, user.Role, ClaimValueTypes.String),
        new Claim(ClaimTypes.Name, user.Email.Split('@')[0], ClaimValueTypes.String),
        new Claim(ClaimTypes.Expiration, TimeSpan.FromDays(365).ToString(), ClaimValueTypes.DaytimeDuration)
    };

    ClaimsIdentity claimsIdentity = new ClaimsIdentity(claimCollection, authenticationType);

    return claimsIdentity;
}

在我的令牌提供程序中间件中,我像这样生成 JWT:

DateTime now = DateTime.Now;

            // Specifically add the jti (nonce), iat (issued timestamp), and sub (subject/user) claims.
            // You can add other claims here, if you want:
            Claim[] claims = new Claim[]
            {
                new Claim(ClaimTypes.Name,validation.ResultObject.Email,ClaimValueTypes.String),
                new Claim(JwtRegisteredClaimNames.Email, validation.ResultObject.Email),
                new Claim(JwtRegisteredClaimNames.Aud, Audience),
                new Claim(JwtRegisteredClaimNames.Iss, issuer),
                new Claim(JwtRegisteredClaimNames.Typ, validation.ResultObject.Role),
                new Claim(JwtRegisteredClaimNames.Jti, await _options.NonceGenerator()),
                new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(now).ToString(), ClaimValueTypes.Integer64),
                new Claim(ClaimTypes.Role, "user")
            };

            // Create the JWT and write it to a string
            JwtSecurityToken jwt = new JwtSecurityToken
            (
                issuer: _options.Issuer,
                audience: _options.Audience,
                claims: claims,
                notBefore: now,
                expires: now.Add(_options.Expiration),
                signingCredentials: _options.SigningCredentials
            );
            string encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

            var response = new
            {
                access_token = encodedJwt,
                expires_in = (int)_options.Expiration.TotalSeconds
            };

            // Serialize and return the response
            context.Response.ContentType = "application/json";
            await context.Response.WriteAsync(JsonConvert.SerializeObject(response, _serializerSettings));

_options 是下一个类:

public class TokenProviderOptions
    {
        /// <summary>
        /// The relative request path to listen on.
        /// </summary>
        /// <remarks>The default path is <c>/token</c>.</remarks>
        public string Path { get; set; } = "api/token";

        /// <summary>
        ///  The Issuer (iss) claim for generated tokens.
        /// </summary>
        public string Issuer { get; set; }

        /// <summary>
        /// The Audience (aud) claim for the generated tokens.
        /// </summary>
        public string Audience { get; set; }

        /// <summary>
        /// The expiration time for the generated tokens.
        /// </summary>
        /// <remarks>The default is five minutes (300 seconds).</remarks>
        public TimeSpan Expiration { get; set; } = TimeSpan.FromDays(360);

        /// <summary>
        /// The signing key to use when generating tokens.
        /// </summary>
        public SigningCredentials SigningCredentials { get; set; }

        /// <summary>
        /// Resolves a user identity given a username and password.
        /// </summary>
        public Func<string, Task<ClaimsIdentity>> IdentityResolver { get; set; }

        /// <summary>
        /// Generates a random value (nonce) for each generated token.
        /// </summary>
        /// <remarks>The default nonce is a random GUID.</remarks>
        public Func<Task<string>> NonceGenerator { get; set; } = new Func<Task<string>>(() => Task.FromResult(Guid.NewGuid().ToString()));

一段时间后我收到错误消息,但仍然不知道出了什么问题。 错误信息是:

WWW-Authenticate:Bearer error="invalid_token", error_description="The 签名无效”

如果您需要,我可以提供更多代码。 谢谢

【问题讨论】:

  • DateTime.AddTimeSpan 作为参数。在您的情况下,_options.Expiration 等于什么?
  • R.Richards:我为您更新了问题,以向您展示 _option 是什么。它是一个设置为 365 天的 TimeSpan。

标签: c# asp.net asp.net-core-mvc jwt


【解决方案1】:

我发现我的 secretKey 是由 GIUD 生成的,每次关闭并重新打开移动应用程序时,都会生成新的 GUID,因为旧令牌不再有效。秘密必须是不变的。将其存储在您的 json 配置文件中。

【讨论】:

    猜你喜欢
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 2010-11-15
    相关资源
    最近更新 更多