尝试访问授权区域时,.NET Core Jwt令牌始终过期

时间:2020-04-17 01:11:38

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

这是我的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

编辑:

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

我使用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;
}

ConfigureServices

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