Jwt 无法有效的发行者或受众

Posted

技术标签:

【中文标题】Jwt 无法有效的发行者或受众【英文标题】:Jwt Unable to valid issuer or audience 【发布时间】:2019-03-15 06:28:08 【问题描述】:

这是我的令牌解码器。当我尝试对其进行解码时,我的主体最终为空,从而导致此错误:

'IDX10208:无法验证受众。 validationParameters.ValidAudience 为 null 或空格,并且 validationParameters.ValidAudiences 为空。'

当我解码我的令牌进行检查时

“nbf”:1539167980,“exp”:1539168580,“iat”:1539167980,“iss”: "http://localhost:55260", "aud": "http://localhost:55260"

这也是我的令牌生成器运行的主机。为什么委托人会导致问题?

public class DecodeToken

    private IConfiguration configuration;
    public DecodeToken(IConfiguration configuration)
    
        this.configuration = configuration;
    

    public AuthenticationDto Decode(String Input)
    
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtAuthentication:SecurityKey"]));
        var handler = new JwtSecurityTokenHandler();
        var tokenSecure = handler.ReadToken(Input) as SecurityToken;
        var validations = new TokenValidationParameters
        
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = key,
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = false
        ;
        SecurityToken securityToken;
        var principal = handler.ValidateToken(Input, validations, out securityToken);
        var jwtSecurityToken = securityToken as JwtSecurityToken;
        if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
        
            throw new SecurityTokenException("Invalid Token");
        
        AuthenticationDto authenticationDto = new AuthenticationDto
        
            Email = principal.Claims.Where(c => c.Type == "Email").Select(c => c.Value).SingleOrDefault(),
            UserName = principal.Claims.Where(c => c.Type == "UserName").Select(c => c.Value).SingleOrDefault(),
            FirstName = principal.Claims.Where(c => c.Type == "FirstName").Select(c => c.Value).SingleOrDefault(),
            LastName = principal.Claims.Where(c => c.Type == "LastName").Select(c => c.Value).SingleOrDefault(),
            PhoneNumber = principal.Claims.Where(c => c.Type == "PhoneNumber").Select(c => c.Value).SingleOrDefault(),
            Id = principal.Claims.Where(c => c.Type == "Id").Select(c => c.Value).SingleOrDefault(),
            ExpiryDateTime = principal.Claims.Where(c => c.Type == "exp").Select(c => c.Value).SingleOrDefault(),
            Roles = principal.Claims.Where(c => c.Type == "Roles").Select(c => c.Value).ToList(),
        ;
        return authenticationDto;
    

这就是我的 Startup.cs 的样子:

services.AddAuthentication(options => 
    options.DefaultAuthenticateScheme = "Jwt";
    options.DefaultChallengeScheme = "Jwt";
)
.AddJwtBearer("Jwt", options =>

    options.TokenValidationParameters = new TokenValidationParameters
    
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtAuthentication:SecurityKey"])),

        ValidateIssuer = true,
        ValidIssuer = Configuration["JwtAuthentication:Issuer"],

        ValidateAudience = true,
        ValidAudience = Configuration["JwtAuthentication:Audience"],

        ValidateLifetime = true, //validate the expiration and not before values in the token

        ClockSkew = TimeSpan.Zero //5 minute tolerance for the expiration date
    ;
    options.Events = new JwtBearerEvents
    
        OnAuthenticationFailed = context =>
        
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            
                context.Response.Headers.Add("Token-Expired", "true");
            
            return Task.CompletedTask;
        
    ;
);

我是不是配置有问题?

【问题讨论】:

【参考方案1】:

您的错误似乎完全有道理。在ConfigureServices 中,您正在设置TokenValidationParameters,以便它验证您的发行人/受众,并且您正在为ValidIssuerValidAudience 提供值,但您没有做同样的事情 em> 在您的 Decode 函数中,您只设置 ValidateIssuerValidateAudience 而不设置您期望的值。您需要在Decode 中的validations 变量上配置这些,如下所示:

var validations = new TokenValidationParameters

    ValidateIssuerSigningKey = true,
    IssuerSigningKey = key,
    ValidateIssuer = true,
    ValidateAudience = true,
    ValidateLifetime = false,
    // Add these...
    ValidIssuer = configuration["JwtAuthentication:Issuer"],
    ValidAudience = configuration["JwtAuthentication:Audience"]
;

【讨论】:

以上是关于Jwt 无法有效的发行者或受众的主要内容,如果未能解决你的问题,请参考以下文章

JSON Web 令牌中的客户端 ID 或多个受众

无法使用 google kms 生成有效的 jwt 签名

无法在角度 6 中检查 AuthGuard 中的 JWT 有效性?

WSO2 APIM - 在 JWT 有效负载中添加用户角色

Auth0 java-jwt 库无法验证有效令牌

使用 keycloak 将自定义键/值添加到 JWT 令牌有效负载或用户