簡體   English   中英

c# asp.net 核心承載錯誤="invalid_token"

[英]c# asp.net core Bearer error="invalid_token"

有人可以幫我解決這個問題嗎? 我正在使用 Postman 測試 API

我正在關注有關 asp.net 內核的教程。

我現在在其身份驗證部分。

我真的不明白錯誤的原因是什么。

在本教程中,它有一個登錄名並返回令牌。

這是登錄代碼。 哪個正在工作。 我知道這是有效的,因為它返回一個令牌。 我也嘗試使用無效的登錄。 它返回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();

我還在 Values Controller 中啟用了[Authorize]

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

這是postman的截圖

在此處輸入圖像描述

我跟着教程。 我粘貼從登錄中收到的令牌。 但它給了我錯誤

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

如果令牌來自登錄,為什么錯誤會給我invalid token 我該如何解決? 我一直在尋找一段時間,但我自己無法解決這個問題。 謝謝你。

更新到Microsoft.AspNetCore.Authentication.JwtBearer v6.0.0+后,我在dotnet 6中遇到了這個問題

作為修復:安裝nuget package System.IdentityModel.Tokens.Jwt Version="6.16.0"

我最近使用 JWT 令牌做了類似的事情,它與 Postman 一起工作得很好。 我創建 JWT 令牌的方法略有不同,在您的情況下,問題可能是由於未指定issuerAudience

你可以嘗試如下。

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

注意:適當更改發行者和密鑰。

我有一個類似的問題,即 .net Core 3 API 無法驗證自己的令牌。

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

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

    app.UseAuthorization();
 }

您收到的錯誤與受眾有關,您應該在選項中包含 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
          };
        });

我有同樣的問題。 請注意Configure 函數中的順序。
app.usemvc (); 應該在底部。 像這樣:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

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

Ram Kumaran ( https://stackoverflow.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

在我的情況下(使用 Keycloak),我添加了一個新的 realm 並忘記更改授權和 Jwt 承載元數據的 URL。 他們仍然指向舊的 realm。 我將 realm 名稱從門戶更改為測試門戶,但提供的令牌不正確,因為它仍然來自門戶 realm。

取自我的 appsettings.json:

"AuthorizationUrl": "https://my.keycloak.id.provider/realms/test-portal/protocol/openid-connect/auth",
"JwtBearerMetadataAddress": "https://my.keycloak.id.provider/realms/test-portal/.well-known/openid-configuration"

我正在尋找類似的問題,但不是這個,

在您的 appsettings.json 您需要添加一個 JWT 部分並使用它們來驗證令牌的發行者和受眾以獲得更安全的令牌

如果你看錯誤的描述:觀眾無效

"BearerToken": {
"Issuer": "the api host",
"Audience": "who use the token",
"Key": "a key to validate your token",
"AccessTokenExpirationMinutes": 25,
"RefreshTokenExpirationMinutes": 50

},

當您添加令牌描述符時,您必須在其中添加發行者和受眾

var descriptor = new SecurityTokenDescriptor
            {
                Issuer = _configuration.Value.Issuer,
                Audience = _configuration.Value.Audience,
                Expires = Clock.UtcNow.ExpiresInMinutes(_configuration.Value.AccessTokenExpirationMinutes),
                Subject = new ClaimsIdentity(userClaims),
                SigningCredentials = new SigningCredentials(authSignInKey, SecurityAlgorithms.HmacSha256),
            };

並在您的啟動 class (.NET 5 或之前)或程序(.NET 6)

您需要添加這樣的身份驗證服務來驗證令牌

builder.Services.AddAuthentication(option =>
{
    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;

}).AddJwtBearer(options =>
{
      options.SaveToken = true;
      options.RequireHttpsMetadata = false;
      options.TokenValidationParameters = new TokenValidationParameters
      {
          ValidateIssuer = true,
          ValidateAudience = true,
          ValidateLifetime = true,
          ValidateIssuerSigningKey = true,
          ValidIssuer = builder.Configuration["BearerToken:Issuer"],
          ValidAudience = builder.Configuration["BearerToken:Audience"],
          IssuerSigningKey = new SymmetricSecurityKey(Convert.FromBase64String(builder.Configuration["BearerToken:Key"])),
      };
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM