将 JwtSecurityToken 与 HttpClient 一起使用

Posted

技术标签:

【中文标题】将 JwtSecurityToken 与 HttpClient 一起使用【英文标题】:Using JwtSecurityToken with HttpClient 【发布时间】:2021-12-03 19:53:59 【问题描述】:

我正在尝试使用 JWT 令牌来查询带有 HttpClient 的 OpenApi 端点。我一直在尝试这样做一段时间,多次尝试不同的东西,比如Base64 编码,只是将 JWT 令牌原始放入 Authorization 标头中,但端点每次都会用“身份验证失败”拆分403 Forbidden . JWT 的验证工作正常,通过Microsoft.IdentityModel.Tokens 完成:

public JwtSecurityToken ValidateCurrentToken(string token)

    var jwksJson = GetKeyInfo();
    var tokenHandler = new JwtSecurityTokenHandler();
    var keyset = JsonWebKeySet.Create(eveJwksJson);
    
    var tokenParameters = new TokenValidationParameters();
    tokenParameters.ValidateIssuerSigningKey = true;
    tokenParameters.ValidateIssuer = true;
    tokenParameters.ValidateAudience = false;
    tokenParameters.ValidateLifetime = true;
    tokenParameters.ValidateActor = false;
    tokenParameters.ValidIssuers = new List<string> "host1", "host2" ;
    tokenParameters.IssuerSigningKey = keyset.Keys.First();

    SecurityToken validatedToken;
    try
    
        tokenHandler.ValidateToken(token, tokenParameters, out validatedToken);
    
    catch(Exception e)
    
        throw new AuthenticationException("Token is not valid: " + e.Message);
    

    var securityToken = (JwtSecurityToken) validatedToken;

但我不知道要在本节的 Authorization 标头中添加什么:

public async Task<HttpResponseMessage> GetResponse(HttpClient httpClient, Uri uri, JwtSecurityToken token)

    HttpRequestMessage httpRequestMessage = new HttpRequestMessage()
    httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", <WHAT TO PUT HERE>);
    httpRequestMessage.Method = HttpMethod.Get;
    httpRequestMessage.RequestUri = uri
    return await httpClient.SendAsync(httpRequestMessage);

有些人建议我尝试urlBase64 对令牌中的JSON 数据进行编码,但没有结果。这一切的文档都与服务有关,我似乎可以找到任何适用于我的问题的文档。

【问题讨论】:

你的 JwtSecurityToken 令牌来自你的签名。您可以检查令牌以确保它在 jwt.io 上有效 @GHDevOps 我需要更多细节,对不起。 JwtSecurityToken 没有 Token 属性。当我查看可以使用的 JwtSecurityToken 数据时,我真的不知道我在寻找什么。我在 JWT 方面不是很强,所以如果这是一个愚蠢的问题,我很抱歉。 有什么问题。你收到了什么错误? @Serge 我收到 403 Forbidden,内容中显示“身份验证失败”消息。我很确定这是因为我在 Authorization 标头中没有做正确的事情。我可以在其某些端点上调用 API 而无需授权,并且效果很好。 API 恐怕需要特别授权。如果只是 jwt 则返回 401 错误。 【参考方案1】:

您已经拥有令牌,ValidateCurrentToken 方法只是进行验证。字符串参数token 是您的 JWT 令牌,它包含三个部分并用点连接,它们是 Header、Payload 和 Signature。 Header 和 Payload 是 base64 编码的。例如,它应该看起来像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

所以你已经有了你需要使用的值,你不需要将JwtSecurityToken转换成字符串。只需在 Authorization 标头中使用 token 参数中的值即可。确保在 Bearer 关键字和令牌之间留一个空格。

您可以参考jwt.io 了解有关 JWT 令牌及其工作原理的更多信息。

【讨论】:

所以我只是把那个字符串值直接添加到 Authorization 标头中? 是的@evilfish,据我查看您的代码,它应该可以工作。

以上是关于将 JwtSecurityToken 与 HttpClient 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

是否将 AspNetUserClaims 中的添加声明添加到 JwtSecurityToken?

如何验证 JwtSecurityToken 自定义属性

JwtSecurityToken 返回错误的过期时间

System.IdentityModel.Tokens.JwtSecurityToken 自定义属性

无法从 JwtSecurityToken 获取签名

无法加载类型“System.IdentityModel.Tokens.JwtSecurityToken”