![](/img/trans.png)
[英]ASP.NET Core WebAPI: Bearer error="invalid_token", error_description="The signature key was not found"
[英]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 令牌的方法略有不同,在您的情況下,問題可能是由於未指定issuer和Audience 。
你可以嘗試如下。
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.