尝试使用 .NET JWT 库生成令牌时出错

本文关键字:令牌 出错 JWT NET | 更新日期: 2023-09-27 17:55:18

我正在尝试使用packageSystem.IdentityModel.Tokens.Jwt来生成令牌。我在网上找到了一些代码示例,非常简单,但后来我遇到了一个我无法弄清楚的错误。这是我正在使用的代码(为简洁起见略有修改):

<%@ Application Language="C#" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Text" %>
<%@ Import Namespace="System.Reflection" %>
<%@ Import Namespace="System.Collections" %>
<%@ Import Namespace="System.IdentityModel.Tokens" %>
<%@ Import Namespace="System.IdentityModel.Tokens.Jwt" %>
<%@ Import Namespace="System.Security.Claims" %>
<%@ Import Namespace="System.IdentityModel.Protocols.WSTrust" %>
<script runat="server">
    public class TestClass
    {
        public static string GetJwtToken()
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var input = "anyoldrandomtext";
            var securityKey = new byte[input.Length * sizeof(char)];
            Buffer.BlockCopy(input.ToCharArray(), 0, securityKey, 0, securityKey.Length);
            var now = DateTime.UtcNow;
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                new Claim( ClaimTypes.UserData,
                "IsValid", ClaimValueTypes.String, "(local)" )
              }),
                TokenIssuerName = "self",
                AppliesToAddress = "https://www.mywebsite.com",
                Lifetime = new Lifetime(now, now.AddMinutes(60)),
                SigningCredentials = new SigningCredentials(new InMemorySymmetricSecurityKey(securityKey),
                  "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
                  "http://www.w3.org/2001/04/xmlenc#sha256"),
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);
            return tokenString;
        }
    }
</script>

我在第 113 行不断收到以下错误(var token = tokenHandler.CreateToken(tokenDescriptor);):

参数 1:无法从"System.IdentityModel.Tokens.SecurityTokenDescriptor"

转换为"Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor"

但我在网上看到很多例子,做事和我做的那样。我还遇到了这篇文章(https://msdn.microsoft.com/en-us/library/jj157089(v=vs.110).aspx),其中陈述了以下内容:

在 WIF 3.5 中,所有 WIF 类都包含在 Microsoft.身份模型组装 (microsoft.identitymicrosoft.identitymodel.dll)。 在 WIF 4.5 中,WIF 类已拆分到以下程序集中:MSCORLIB (mscorlib.dll), System.IdentityModel (System.IdentityModel.dll), System.IdentityModel.Services (System.IdentityModel.Services.dll),以及 System.ServiceModel (System.ServiceModel.dll).

WIF 3.5 类都包含在其中一个 Microsoft.身份模型命名空间;例如 Microsoft.IdentityModel, Microsoft.IdentityModel.Tokens, Microsoft.IdentityModel.Web,等等。在 WIF 4.5 中,WIF 类 现在分布在 System.IdentityModel 命名空间中, System.Security.Claims 命名空间和 System.ServiceModel.Security 命名空间。除了这种重组之外,一些 WIF 3.5 类 已在 WIF 4.5 中删除。

为了调试起见,我尝试切换到使用 Microsoft.* 命名空间作为 SecurityTokenDescriptor,然后我收到另一系列错误,指出 TokenIssuerName、AppliesToAddress 和 Lifetime 不是该类的有效属性。然而,当我在线查看文档时,似乎这些属性确实存在于Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor上。然而,在我的Visual Studio中,当我为该类执行"转到定义"时,它们不在那里,这让我相信我的Visual Studio中存在某种配置问题。在我的包管理器中,它显示我已安装Microsoft.IdentityModel.Tokens v5.0.0。我还将项目更改为 .NET Framework 4.5.1,因为 JWT 库需要它。除此之外,我不知道还能去哪里寻找。

尝试使用 .NET JWT 库生成令牌时出错

我在升级时遇到了类似的 OpenID Connect 库,它以前在 Microsoft.IdentityModel.Protocol.Extensions 包中(依赖于 JWT 包的 4.0.2),但现在是Microsoft.IdentityModel.Protocols.OpenIdConnect依赖于 2.0.0 的 Microsoft.IdentityModel.Protocols(取决于 JWT 包的 5.0.0

)。

删除任何Microsoft.IdentityModel*System.IdentityModel*软件包,并仅安装取决于Microsoft.IdentityModel.Tokens的最新 (5.0.0) System.IdentityModel.Tokens.Jwt 软件包。

您需要为这些命名空间使用语句:

    Microsoft.IdentityModel.Tokens
  • (但不是System.IdentityModel.Tokens)
  • System.IdentityModel.Tokens.Jwt
  • 系统.安全.声明

Microsoft简化了一些参数,使其更像您对其他平台的 JWT 库的期望,因此SecurityTokenDescriptor属性略有不同:

var tokenDescriptor = new SecurityTokenDescriptor
{
    Subject = new ClaimsIdentity(new[]
    {
        new Claim( ClaimTypes.UserData,
        "IsValid", ClaimValueTypes.String, "(local)" )
    }),
    Issuer = "self",
    Audience = "https://www.mywebsite.com",
    Expires = now.AddMinutes(60),
    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(securityKey), SecurityAlgorithms.HmacSha256),
};

请注意,SecurityAlgorithms.HmacSha256 是"HS256"的字符串常量,就像您在大多数其他库中使用的那样。 使用上面的代码加上问题中的示例,您应该能够生成有效的 JWT。