【问题标题】:.NET Core Jwt Token always expired when trying to access Authorized area.NET Core Jwt 令牌在尝试访问授权区域时总是过期
【发布时间】:2020-07-30 10:05:45
【问题描述】:

这是我的 Startup.cs

services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = "bearer";
    x.DefaultChallengeScheme = "bearer";
})
.AddJwtBearer("bearer",x =>
{
    x.RequireHttpsMetadata = false;
    x.SaveToken = true;
    //x.TokenValidationParameters = tokenValidationParameters;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKey")),
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidIssuer = Environment.GetEnvironmentVariable(MS_Jwt_Issuer),
        ValidAudience = Environment.GetEnvironmentVariable(MS_Jwt_Issuer),
        ClockSkew = TimeSpan.Zero,
    };
    x.Events = new JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            {
                context.Response.Headers.Add("Token-Expired", "true");
            }
            return Task.CompletedTask;
        }
    };
});


services.AddResponseCaching();
services.AddCors(c =>
{
    c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
});

这是我设置令牌的方式:

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKey"));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var tokenDescriptor = new SecurityTokenDescriptor
{
    Subject = new ClaimsIdentity(claims),
    Expires = DateTime.UtcNow.AddDays(10),
    SigningCredentials = credentials,
    IssuedAt = DateTime.UtcNow,
    Issuer = Environment.GetEnvironmentVariable(MS_Jwt_Issuer),
    Audience = Environment.GetEnvironmentVariable(MS_Jwt_Issuer),
};

var token = tokenHandler.CreateToken(tokenDescriptor);
var refreshToken = tokens.GenerateRefreshToken();
var processedToken = tokenHandler.WriteToken(token);

每当我进行身份验证时,我都能正确取出令牌。但是,当我尝试访问受 [Authorize] 保护的类时,会出现以下异常:

抛出异常: 'Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException' 在 Microsoft.IdentityModel.Tokens.dll

这是我的令牌示例。它使用我的密钥验证成功,并且显示的到期日期正确且未过期:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJQaG9uZU51bWJlciI6IjEyMzIxMjMxMjMiLCJuYmYiOjE1ODcwNTAxOTksImV4cCI6MTU4NzkxNDE5OSwiaWF0IjoxNTg3MDUwMTk5LCJpc3MiOiJTUiIsImF1ZCI6IlNSIn0.WbEJq_PAOLvra1ZUwtQEKH9FRBDdb2byw26miUm-K-E P>

编辑:

当我尝试手动验证令牌时,它验证成功并且没有过期。但是由于某种原因,[Authorize] 将其标记为已过期

【问题讨论】:

  • 有时问题可能是 ValidateLifetime = true,尝试将其设为 false 并尝试。
  • ValidateLifetime = 假作品。但是,我需要知道为什么将其设置为 true 不起作用?

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


【解决方案1】:

你是否在 Startup 的 Configure 方法中添加了 UseAuthentication() 中间件?

【讨论】:

  • 我做到了。这是我的 ValidateLifeTime 的问题。当我将其设置为 false 时,我的授权工作。
【解决方案2】:

我使用 JWT 创建令牌。这对我有用,希望对你有用

 public TokenResponse BuildToken(string username)
    {

        var now = DateTime.UtcNow;

        var claims = new Claim[]
        {
                new Claim(JwtRegisteredClaimNames.Sub, username),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.FamilyName, username),
                new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(), ClaimValueTypes.Integer64)
        };

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

        var jwt = new JwtSecurityToken(
            issuer: "Iss",
            audience: "Audience",
            claims: claims,
            notBefore: now,
            expires: now.Add(TimeSpan.FromDays(30)),
            signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
        );
        var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
        var responseJson = new TokenResponse
        {
            access_token = encodedJwt,
            expires_in = (int)TimeSpan.FromDays(30).TotalDays
        };

        return responseJson;
}

配置服务

var authenticationProviderKey = "bearer";


        var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("Secret"));
        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = signingKey,
            ValidateIssuer = true,
            ValidIssuer = "Iss",
            ValidateAudience = true,
            ValidAudience = "Audience",
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero,
            RequireExpirationTime = true,
        };

        services.AddAuthentication(o =>
        {
            o.DefaultAuthenticateScheme = authenticationProviderKey;
        })
        .AddJwtBearer(authenticationProviderKey, x =>
        {
            x.RequireHttpsMetadata = false;
            x.TokenValidationParameters = tokenValidationParameters;
            x.Events = new JwtBearerEvents
            {
                OnAuthenticationFailed = context =>
                {
                    if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                    {
                        context.Response.Headers.Add("Token-Expired", "true");
                    }
                    return Task.CompletedTask;
                }
            };
        });

配置

 app.UseAuthentication();
 app.UseAuthorization();

【讨论】:

  • 我的配置和你的差不多。
  • 我在我的项目中使用你的配置我没有任何问题
  • 这是我在github的项目你可以看到github.com/RezaJenabi/Ecommerce
猜你喜欢
  • 2018-10-07
  • 2019-06-05
  • 2016-09-09
  • 2019-12-22
  • 2020-04-28
  • 2019-04-04
  • 2020-05-05
  • 2020-03-28
  • 2023-03-16
相关资源
最近更新 更多