c# asp.net core Bearer error="invalid_token"

Posted

技术标签:

【中文标题】c# asp.net core Bearer error="invalid_token"【英文标题】: 【发布时间】:2019-06-21 02:14:49 【问题描述】:

有人可以帮我解决这个问题吗?我正在使用 Postman 测试 API

我正在关注一个关于 asp.net core 的教程。

我现在正处于其身份验证部分。

我真的不明白错误的原因是什么。

在教程中,它有一个登录并返回令牌。

这是登录代码。哪个正在工作。我知道这是有效的,因为它返回一个令牌。我也尝试使用无效的登录。它返回401 Unauthorized 但是当我使用在数据库中找到的正确登录凭据时。它返回令牌

[HttpPost("login")]
public async Task<IActionResult> Login(UserForLoginDto userForLoginDto)
    
        var userFromRepo = await _repo.Login(userForLoginDto.Username.ToLower(), userForLoginDto.Password);

        if (userFromRepo == null)
            return Unauthorized();

        var claims = new[]
        
            new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id.ToString()),
            new Claim(ClaimTypes.Name, userFromRepo.Username)
        ;

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config.GetSection("AppSettings:Token").Value));

        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);

        var tokenDescriptor = new SecurityTokenDescriptor
        
            Subject = new ClaimsIdentity(claims),
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = creds
        ;

        var tokenHandler = new JwtSecurityTokenHandler();

        var token = tokenHandler.CreateToken(tokenDescriptor);

        return Ok(new 
            token = tokenHandler.WriteToken(token)
        );

那么教程的下一部分就是限制访问。用户应先登录才能查看内容。

下面是代码

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
                options.TokenValidationParameters = new TokenValidationParameters
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                    ValidateIssuer = false
                ;
            );

然后启用

app.UseAuthentication();

我还在值控制器中启用了[Authorize]

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

这是邮递员的截图

我按照教程进行操作。我粘贴从登录中收到的令牌。但它给了我错误

WWW-Authenticate →Bearer error="invalid_token", error_description="The audience is invalid"

如果令牌来自登录,为什么错误会给我invalid token?我该如何解决?我一直在寻找一段时间,但我自己无法解决这个问题。谢谢。

【问题讨论】:

如果我省略了 contentType,就会出现这个错误 @daremachine。抱歉,我不明白 contentType。请问能不能展开。我来自WPF。我真的不明白 你能显示你的 api/values,你有没有为此设置任何授权策略? @PSK 是的。授权策略已启用。请检查帖子。我更新了它,忘了提及它。对不起 @Ramonbihon 我想知道你是如何解决这个问题的? 【参考方案1】:

我最近使用与 Postman 配合良好的 JWT 令牌做了类似的事情。我创建 JWT 令牌的方法略有不同,在您的情况下,问题可能是由于未指定 颁发者受众。 p>

你可以尝试如下。

   var claims = new List<Claim>
    
        new Claim(ClaimTypes.WindowsAccountName, this.User.Identity.Name)
    ;
    Claim userIdClaim = new Claim("UserId", "12345");
    claims.Add(userIdClaim);
    //Avoid Replay attack
    claims.Add(new Claim(ClaimTypes.GivenName, "User GivenName"));
    claims.Add(new Claim(ClaimTypes.Surname, "UserSurname"));
    claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()));

    string[] roles = "Role1,Role2,Role23".Split(",");

    foreach (string role in roles)
    
        claims.Add(new Claim(role, ""));
    

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("veryVerySecretKey"));
    var key1 = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("ASEFRFDDWSDRGYHF")); 
    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var encryptingCreds = new EncryptingCredentials(key1, SecurityAlgorithms.Aes128KW, SecurityAlgorithms.Aes128CbcHmacSha256);
    var handler = new JwtSecurityTokenHandler();
    var t = handler.CreateJwtSecurityToken();
    var token = handler.CreateJwtSecurityToken("http://localhost:61768/", "http://localhost:61768/"
        , new ClaimsIdentity(claims)
        , expires: DateTime.Now.AddMinutes(1)
        , signingCredentials: creds
        , encryptingCredentials :encryptingCreds
        , notBefore:DateTime.Now
        ,  issuedAt:DateTime.Now);
    return new JwtSecurityTokenHandler().WriteToken(token);

我的ConfigureServices 看起来像

services.AddAuthentication()
            .AddJwtBearer(options =>
             
                 options.RequireHttpsMetadata = false;
                 options.SaveToken = true;
                 options.TokenValidationParameters = new TokenValidationParameters
                 
                     ValidateIssuer = true,
                     ValidateAudience = true,
                     ValidateLifetime = true,
                     ValidateIssuerSigningKey = true,
                     ValidIssuer = "http://localhost:61768/",
                     ValidAudience = "http://localhost:61768/",
                     TokenDecryptionKey= new SymmetricSecurityKey(Encoding.UTF8.GetBytes("ASEFRFDDWSDRGYHF")),
                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("veryVerySecretKey")),
                     ClockSkew = TimeSpan.Zero
                 ;
             );

注意:适当更改颁发者和密钥。

【讨论】:

我没有尝试过您的解决方案,但感谢您抽出宝贵时间。就我而言,解决方案是 ValidateAudience = false。【参考方案2】:

我遇到了类似的问题,即 .net Core 3 API 无法验证自己的令牌。

我的解决方案是在 Startup/Configure() 中,将 app.UseAuthentication() 放在 app.UseAuthorization() 之前。

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 
    app.UseAuthentication();

    app.UseAuthorization();
 

【讨论】:

那是我的问题。【参考方案3】:

您收到的错误与受众有关,您应该在选项中包含 ValidAudience 或将 ValidateAudience 设置为 false。

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options => 
            options.TokenValidationParameters = new TokenValidationParameters
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
            ValidateIssuer = false,
            ValidateAudience = false
          ;
        );

【讨论】:

【参考方案4】:

我遇到了同样的问题。请注意配置函数中的顺序。app.usemvc (); 应该在底部。像这样:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

    if (env.IsDevelopment())
    
        app.UseDeveloperExceptionPage();
    

    app.UseAuthentication();
    app.UseMvc();

【讨论】:

【参考方案5】:

Ram Kumaran (https://***.com/a/54396550/8210755) 答案对我有用,它可能发生在更新到 net core 3.1 或更新 IdentityServer 到 4.3.1 之后

我已经用 AddJwtBearer 替换了注释代码

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            //.AddIdentityServerAuthentication(options =>
            //
            //    options.Authority = Configuration.GetSection("IdentityServerUrl").Value;
            //    options.RequireHttpsMetadata = false;
            //    options.ApiName = "api1";
            //);
            .AddJwtBearer(o =>
             
                 o.Authority = Configuration.GetSection("IdentityServerUrl").Value;
                 o.RequireHttpsMetadata = false;
                 o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                 
                     ValidateAudience = false
                 ;
             );

有用的文档参考: https://docs.identityserver.io/_/downloads/en/latest/pdf/ 在类似概念证明的假中使用 ValidateAudience

【讨论】:

以上是关于c# asp.net core Bearer error="invalid_token"的主要内容,如果未能解决你的问题,请参考以下文章

ASP.Net Core 3.0 JWT Bearer Token 没有 SecurityTokenValidator 可用

使用 ADFS 的 JWT Bearer 身份验证将 ASP.NET Framework 迁移到 ASP.NET Core 3.1

每当我发送包含 Bearer 令牌的请求时,ASP.Net Core API 总是返回 401 未授权

Asp.Net core Authorization with Bearer token status Unauthorized 401 with Valid token

JWT Bearer ASP.Net Core 3.1 用户在服务器上为空白

带有 JWT Bearer 令牌和 ASP.NET Core 2 WebApi 的 Azure AD 用户信息