我的客户端正在发送带有一些请求的 jwt 令牌。几乎所有请求都命中使用 [Authorize] 属性的 Web API 控制器。有了这个,我确信我的 jwt 令牌已正确验证,但对于某些端点,实际上只是想获取 JWT 令牌并获取子值。我使用此扩展方法来执行此操作:
public static class HttpContextAccessorExtensions
{
public static string GetUserIdFromToken(this IHttpContextAccessor httpContextAccessor)
{
if (httpContextAccessor == null)
{
throw new ArgumentNullException(nameof(httpContextAccessor));
}
var context = httpContextAccessor.HttpContext;
string userId = null;
if (httpContextAccessor != null)
{
if (context != null)
{
var request = context.Request;
if (request != null)
{
request.Headers.TryGetValue("Authorization", out var bearer);
if (bearer.Any())
{
string t = bearer[0].Split(" ")[1];
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadToken(t) as JwtSecurityToken;
var utcNow = DateTime.UtcNow;
if (utcNow >= token.ValidFrom &&
utcNow <= token.ValidTo)
{
userId = token.Claims.FirstOrDefault(_ => _.Type.Equals("sub")).Value;
}
else
{
userId = String.Empty;
}
}
}
}
}
return userId;
}
}
我在这里唯一的问题是 jwt 令牌未经验证,所以我猜测"坏人"可能只是与有效的日期时间混合在一起,并继续延长令牌生命周期。如果我错了,请纠正我。
我想知道的是:有没有办法验证令牌?我知道 JwtSecurityTokenHandler 可以调用"ValidateToken",但这种方法需要一个签名密钥,我真的不知道如何获得这个。我使用 IdentityServer 4 生成令牌。是否有一些简单的方法可以将密钥注入 IoC 以便我可以获取它,或者是否有一种我不知道的简单方法来验证令牌?
任何帮助不胜感激
由于您的访问令牌是由 IdentityServer4 生成的,因此您应该使用 IS4 侦测端点对其进行验证。 这将为您提供有关它是否有效以及它是否仍然处于活动状态的明确答案。
有关内省端点的信息位于 IS4 文档中,网址为: http://docs.identityserver.io/en/latest/endpoints/introspection.html
如这些文档中所述,与终结点交互的最简单方法可能是使用 IdentityModel 客户端库(通过 NuGet 添加包(,它将 IntrospectTokenAsync(( 扩展方法添加到 HttpClient,并返回包含所需信息的 TokenIntrospectionResponse 对象。
身份模型客户端侦测端点文档: https://identitymodel.readthedocs.io/en/latest/client/introspection.html
在控制器中,您可以执行以下操作:
if(HttpContext.User.Identity.IsAuthenticated)
{
var claims = HttpContext.User.Claims;
}
您可以检查索赔以获取感兴趣的任何信息。 该经过身份验证的用户身份已经过验证,并且无论是否应用授权属性都可用。 如果用户的 cookie 已过期等,则返回 false。.
我想知道的是:有没有办法验证令牌?我知道 JwtSecurityTokenHandler 可以调用"ValidateToken",但这种方法需要一个签名密钥,我真的不知道如何获得这个。我使用 IdentityServer 4 生成令牌。
验证身份服务器颁发的JWT令牌(使用密钥对颁发/验证令牌(时,专门用于验证签名。API/资源服务器将下拉(并可能缓存(位于 OIDC 端点https://xxx/.well-known/openid-configuration
的身份提供程序发现文档。本文档包含允许资源服务器验证令牌、从jwks_uri
读取可用密钥的材料。
使用密钥对 menans 由 IDS4 使用私钥签名的 JWT 令牌。JWT 令牌是未经加密的数字签名 JSON 有效负载,其中包含用于标识用户/角色的不同属性(声明(。签名是 JWT 的最后一部分,需要用于验证有效载荷。此签名是使用标头(例如 RS256(中描述的算法生成的,以防止未经授权的访问。在你的api中,你可以使用IDS4(jwks_uri
(发布的公钥来验证JWT令牌的签名。有关 JWT 令牌的更多详细信息,请参阅此文档。
您可以使用JwtBearerAuthentication
中间件IdentityServer.AccessTokenValidation
中间件将有助于完成该过程。这里的代码示例仅供参考。如果要手动验证 JWT 令牌。单击此处获取代码示例。
我在这里唯一的问题是 jwt 令牌未经验证,所以我猜测"坏人"可能只是与有效的日期时间混合在一起,并继续延长令牌生命周期。
不建议在没有验证的情况下使用令牌。由于JWT令牌的签名部分是加密/编码使用的(标头+有效载荷(,即使有人更改了声明(过期时间(,也不会通过验证,因为他无法知道身份服务器的私钥来颁发正确的签名。