c# - 尝试使用 .NET JWT 库生成 token 时出错

标签 c# asp.net jwt

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

<%@ 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 ),其中陈述了以下内容:

In WIF 3.5, all of the WIF classes were contained in the Microsoft.IdentityModel assembly (microsoft.identitymicrosoft.identitymodel.dll). In WIF 4.5, the WIF classes have been split across the following assemblies: mscorlib (mscorlib.dll), System.IdentityModel (System.IdentityModel.dll), System.IdentityModel.Services (System.IdentityModel.Services.dll), and System.ServiceModel (System.ServiceModel.dll).

The WIF 3.5 classes were all contained in one of the Microsoft.IdentityModel namespaces; for example, Microsoft.IdentityModel, Microsoft.IdentityModel.Tokens, Microsoft.IdentityModel.Web, and so on. In WIF 4.5, the WIF classes are now spread across the System.IdentityModel namespaces, the System.Security.Claims namespace, and the System.ServiceModel.Security namespace. In addition to this reorganization, some WIF 3.5 classes have been dropped in WIF 4.5.

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

最佳答案

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

删除所有 Microsoft.IdentityModel*System.IdentityModel* 包,并仅安装最新的 (5.0.0) System.IdentityModel.Tokens .Jwt 依赖于 Microsoft.IdentityModel.Tokens 的包。

您需要为这些 namespace 使用 using 语句:

  • 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。

关于c# - 尝试使用 .NET JWT 库生成 token 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38231321/

相关文章:

node.js - Passport jwt未经授权

c# - 关于使用Hadoop.WebHDFSClient时文件创建的403,尽管能够在HDFS中创建文件夹

c# - 为什么 Visual Studio 在 Razor (.cshtml/.razor) 中突出显示双花括号?

c# - C# 中未使用的 "using"指令的性能影响

c# - 为 WCF 服务启用 HTTPS 流量。将流量 http 更改为 https 的问题

c# - 如果任何列值为空,则删除数据表行c#

javascript - 我应该将 Cognito 用户池与其他社交 IDPS 联合起来,还是通过用户池本身进行社交登录

Azure 应用服务身份验证/授权和自定义 JWT token

c# - 如何在不处理上下文的情况下刷新 Entity Framework 连接

c# - jquery new Date() 在本地工作但不在线