无法获得ASP .NET Core 2.2来验证我的JWT [英] Can't get asp .net core 2.2 to validate my JWT
问题描述
(TL; DR:检查最近的更新)
(TL;DR: check the last update)
与此有关的第一个问题是,.net核心的不同版本之间的API有所更改.
The first issue with this is that the API has changed between the different versions of .net core.
第二个问题是,我在网上找到的每个示例都稍有不同,关于做什么是什么没有真正的权威性答案;而是我一直在寻找哦,改变对我有用的东西"的帖子,但是看起来像我一样的每个人都在尝试它,而不是完全了解.
The second one is that every example I find online is slightly different with not real authoritative answer as to what does what; rather I keep finding posts with 'oh, changing this worked for me', but it looks like everyone is, like me, experimenting with it rather than having a full understanding.
无论如何,这是代码:
Services.AddAuthentication(A =>
{
A.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
A.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(O =>
{
O.RequireHttpsMetadata = false;
O.SaveToken = true;
O.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(AuthJWTPublicKey)),
ValidateIssuer = false,
ValidateAudience = false
};
});
我有一个有效的JWT,但对控制器的任何调用都会导致立即错误401.
I have a valid JWT but any call to my controller results in an immediate error 401.
我尝试用以下方式装饰控制器:
I have tried to decorate the controller with:
[授权]
[Authorize]
[Authorize(Roles ="offline_access")]
[Authorize(Roles = "offline_access")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme,角色="offline_access")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Roles = "offline_access")]
但没有运气
JWT的内容是:
{
"jti":"837c2dd1-cca5-491e-84a4-b17429366df5",
"exp":1558355152,
"nbf":0,
"iat":1558354852,
"iss":"xxxx",
"aud":"account",
"sub":"4ed1c313-c692-44db-86d3-7605f3e2c2c1",
"typ":"Bearer",
"azp":"test-app",
"auth_time":1558354850,
"session_state":"e40c9a95-ae8a-4d6e-b2a4-ad5e833867ea",
"acr":"1",
"realm_access":{
"roles":[
"offline_access",
"uma_authorization"
]
},
"resource_access":{
"account":{
"roles":[
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope":"openid email profile",
"email_verified":true,
"name":"firstd6d05 last29954",
"preferred_username":"xxxx",
"given_name":"firstd6d05",
"family_name":"last29954",
"email":"xxxx",
"group":[
"/Administrators"
]
}
我的目标纯粹是验证JWT的签名(并最终证明它已过期)并可以访问控制器中的令牌.
My goal is purely to verify the signature of the JWT (and eventually it's expiration) and have access to the token in the controller.
我正在将JWT通过标头,位于授权"下,并且令牌前面带有文本承载者".
I am passing the JWT through the header, under 'Authorization' and with the text 'Bearer' in front of the token.
我想念什么?
按照以下答案,我进行了以下更改:
Following the answer below, I did the following change:
我添加了:
Services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
,然后在休息时添加以下类
and then added the following class with a break
internal class ClaimsTransformer : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
Debugger.Break();
}
}
但是我仍然得到带有Keycloak令牌的401;因此看起来好像没有被拒绝之前就到达了索赔转换器.
but I am still getting a 401 with the Keycloak token; so it looks like it doesn't get to the claims transformer before being rejected.
我添加了ASP的调试输出.
I added the debug output of ASP.
它位于: https://pastebin.com/qvGsQG6j
相关的部分似乎是:
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
=> ConnectionId:0HLN4CPASJL8F => RequestId:0HLN4CPASJL8F:00000001 RequestPath:/helpers/log => Test.WebControllers.HelpersController.GetLog (Test)
Authorization failed.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Info:Authorization failed.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Info:Authorization failed.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
=> ConnectionId:0HLN4CPASJL8F => RequestId:0HLN4CPASJL8F:00000001 RequestPath:/helpers/log => Test.WebControllers.HelpersController.GetLog (Test)
Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Info:Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Info:Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
=> ConnectionId:0HLN4CPASJL8F => RequestId:0HLN4CPASJL8F:00000001 RequestPath:/helpers/log => Test.WebControllers.HelpersController.GetLog (Test)
此特定行可能会解释该问题:
This specific line may explain the issue:
针对过滤器'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'的请求的授权失败
Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'
但是失败"在我看来有点模糊.
but 'failed' seems a bit vague to me.
最后一次测试:
我有这个令牌:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoibXkgbmFtZSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyI6Im5vQGVtYWlsLmNvbSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvZXhwaXJhdGlvbiI6IjA1LzMxLzIwMTkgMDA6MTM6MjAiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zaWQiOiI3Y2FjZjdiNS04NjY5LTQ2OWUtOTg4NS1kNDgwNGYyOGNjNGEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA5LzA5L2lkZW50aXR5L2NsYWltcy9hY3RvciI6ImQyZjZiNzI0LWE0ZjktNGJkZC1hNjQ3LTRkM2UxYTU5NjhkZSIsIm5iZiI6MTU1OTE3NTIwMCwiZXhwIjoxNTU5MjYxNjAwLCJpc3MiOiJ0ZXN0IiwiYXVkIjoidGVzdC1hcHAifQ.y42RUvMM69aDTvCydoU3mOKu2giub6OvKpd-RNVmom4
使用键:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjayVuqZOuKK38rhsRwrRGzVcv/7b4fHXrzpol3K5TTAPttNUaQvCKQD7BQN+V8nvkBsQcxPk5ONnxzbFb/npENC4UtwK5J6iiVrinE7sDrWZQNo9LkwbuG9x0fuuf8U3H2CnwZEfFaf2kbU1v7XosNGi+aYASupvhwoiJtK+17ZPloxSQy3Qny2tQWi7Dh/Cr5+m5JBy6HeGLq2cq+oalFYzrGGmQXndLtJpBZgrPd7nR6lJSMiRcJtcpxTJbYTEVVXoB0SR1bPmYYB/6y7klVDVedTow+1mwZrDMrbRiTBPSifCIBs3rxLQaL207blg+kj+EVLED5fZSOBlOyTOYQIDAQAB
它解码为(经jwt.io测试):
it decodes to (as tested by jwt.io):
{
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "my name",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress": "no@email.com",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/expiration": "05/31/2019 00:13:20",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid": "7cacf7b5-8669-469e-9885-d4804f28cc4a",
"http://schemas.xmlsoap.org/ws/2009/09/identity/claims/actor": "d2f6b724-a4f9-4bdd-a647-4d3e1a5968de",
"nbf": 1559175200,
"exp": 1559261600,
"iss": "test",
"aud": "test-app"
}
它是由以下代码生成的:
it is generated by the following code:
var Expiration = DateTime.UtcNow + TimeSpan.FromDays(1);
var Identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "my name"),
new Claim(ClaimTypes.Email, "no@email.com"),
new Claim(ClaimTypes.Expiration, Expiration.ToString(CultureInfo.InvariantCulture)),
new Claim(ClaimTypes.Sid, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.Actor, Guid.NewGuid().ToString()),
});
var Token = new JwtSecurityToken
(
issuer: "test",
audience: "test-app",
claims: Identity.Claims,
notBefore: DateTime.UtcNow,
expires: Expiration,
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_JwtRsaPublicKey)), SecurityAlgorithms.HmacSha256)
);
var TokenString = new JwtSecurityTokenHandler().WriteToken(Token);
return TokenString;
在asp中,我有以下代码:
In asp, I have the following code:
Services.AddAuthentication(A =>
{
A.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
A.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(O =>
{
O.RequireHttpsMetadata = false;
O.SaveToken = true;
O.IncludeErrorDetails = true;
O.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(AuthJWTPublicKey)),
ValidateIssuer = false,
ValidateAudience = false
};
});
并且我有一个控制器方法:
and I have a controller method with:
[Authorize]
但是我一直得到401,无论我尝试什么,我都会得到401 ...
But I keep getting a 401, no matter what I try, I get a 401...
即使我将ValidateIssuerSigningKey设置为false.我得到401
Even if I set ValidateIssuerSigningKey to false. I get a 401
设置为:
在ConfigureServices中,我有:
In ConfigureServices, I have:
Services.AddMvc()
and the code above
在配置"中,我有:
Application.UseAuthentication();
Application.UseMvc(Routes => { Routes.MapRoute("default_route", "{controller}/{action}/{id?}"); });
推荐答案
根据
....
public const string Role = ClaimTypeNamespace + "/role";
...
常量 The const 请注意,您的控制器要求使用 Note your controller requires a role of 换句话说,它期望解码后的 In other words, it expects the decoded 但是,您可以通过以下方式配置角色: However, you configure the roles in the following way: 最简单的方法是重建令牌以配置 The easiest way is rebuild the token to config a role of 或者您可以通过注册自定义 Or you could transform the keycloak's style claim to Microsoft's style by registering a custom 这篇关于无法获得ASP .NET Core 2.2来验证我的JWT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!ClaimTypes.Role
是 http://schemas.microsoft.com/ws/2008/06/identity/claims/role
ClaimTypes.Role
is http://schemas.microsoft.com/ws/2008/06/identity/claims/role
offline_access
角色:offline_access
:[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Roles = "offline_access")]
JWT
具有 http://schemas.microsoft.com/ws/2008/06/identity/claims/role
的属性来配置角色:JWT
has a property of http://schemas.microsoft.com/ws/2008/06/identity/claims/role
to configure the roles:
{
"nbf": ...,
"exp": ...,
"iss": ...,
"aud": ...,
...,
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role": [
"offline_access",
"...other roles"
],
}
"realm_access":{
"roles":[
"offline_access",
"uma_authorization"
]
},
offline_access
的角色:offline_access
: ClaimsIdentity identity = new ClaimsIdentity(new[] {
new Claim(ClaimTypes.Name,"1024"),
new Claim(ClaimTypes.Role,"offline_access"),
new Claim(ClaimTypes.Role,"...other roles"),
// ... other claims
});
var token = new JwtSecurityToken
(
issuer: _issuer,
audience: _audience,
claims: identity.Claims,
expires: expiry,
notBefore: DateTime.UtcNow,
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(mykeyname)),
SecurityAlgorithms.HmacSha256)
);
var tokenStr = tokenHandler.WriteToken(token);
IClaimsTransformation
将密钥斗篷的样式声明转换为Microsoft的样式,请参见ASP.NET Core团队的示例IClaimsTransformation
, see a Sample by ASP.NET Core Team https://github.com/aspnet/AspNetCore/blob/658b37d2bd3b0da2c07e25b53fa5c97ce8d656d3/src/Security/samples/ClaimsTransformation/Startup.cs#L34