我的客户端正在向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中,以便我可以获取它,或者有一种简单的方法可以验证我不知道的令牌?
感谢您的帮助
答案 0 :(得分:1)
由于访问令牌是由IdentityServer4生成的,因此您应该使用IS4自省端点对其进行验证。这将为您提供有关其是否有效以及是否仍处于活动状态的明确答案。
有关自省端点的信息位于IS4文档中,位于: http://docs.identityserver.io/en/latest/endpoints/introspection.html
如在这些文档中所引用的那样,与端点进行交互的最简单方法可能是使用IdentityModel客户端库(通过NuGet添加软件包),该库将IntrospectTokenAsync()扩展方法添加到HttpClient并返回TokenIntrospectionResponse对象,该对象具有您需要的信息。
IdentityModel客户端自省端点文档: https://identitymodel.readthedocs.io/en/latest/client/introspection.html
答案 1 :(得分:1)
您可以在控制器内部执行以下操作:
if(HttpContext.User.Identity.IsAuthenticated)
{
var claims = HttpContext.User.Claims;
}
,您可以检查索赔中是否有任何感兴趣的信息。 身份验证的用户身份已通过验证,并且无论是否应用Authorize属性都可用。如果用户的cookie已过期等,将返回false。
答案 2 :(得分:1)
我想知道的是:我是否可以验证令牌?我知道JwtSecurityTokenHandler可以调用“ ValidateToken”,但是此方法需要一个签名密钥,而且我真的不知道如何获取它。我使用IdentityServer 4生成令牌。
在验证由Identity Server发行的JWT令牌时(使用密钥对来发行/验证令牌),特定于验证签名。 API /资源服务器将拉低(并可能缓存)位于OIDC端点 <script async src="https://www.googletagmanager.com/gtag/js?id=UA-xxxxxx-x"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'UA-xxxxxxxx-x', {
'custom_map': {
'dimension1': 'district_state',
'dimension2': 'district_name',
'dimension3': 'user_type',
'dimension4': 'district_school_name'
}
});
gtag('event', 'data', {
'district_state': $('#ctl00_hdnState').val(),
'district_name': $('#ctl00_hdnDistrict').val(),
'district_school_name':$('#ctl00_hdnProvider').val(),
'user_type': $('#ctl00_HdnRole').val()
});
上的身份提供者发现文档。本文档包含允许资源服务器验证令牌,从https://xxx/.well-known/openid-configuration
读取可用密钥的材料。
使用密钥对意味着由IDS4用私钥签名的JWT令牌。 JWT令牌是未加密的数字签名JSON有效负载,其中包含用于标识用户/角色的不同属性(声明)。签名是JWT的最后一部分,需要用于验证有效负载。该签名是使用标题(例如,RS256)中描述的算法生成的,以防止未经授权的访问。在您的api中,您可以使用IDS4(jwks_uri
)发布的公钥来验证JWT令牌的签名。有关JWT令牌的更多详细信息,请参考this document。
您可以使用jwks_uri
中间件或JwtBearerAuthentication
中间件来帮助完成该过程。代码示例here供您参考。如果要手动验证JWT令牌。点击here以获得代码示例。
我唯一的问题是jwt令牌没有经过验证,因此我猜想一个“坏人”可能会与有效日期时间混合在一起,并继续延长令牌寿命。
不建议在未验证令牌的情况下使用令牌。由于JWT令牌的签名部分是加密/编码使用(标头+有效载荷),即使有人更改了声明(过期时间),它也不会通过验证,因为他不知道Identity Server的私钥来发布正确的签名