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

时间:2023-03-27
本文介绍了尝试使用 .NET JWT 库生成令牌时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

I'm trying to use package System.IdentityModel.Tokens.Jwt to generate a token. I found some code samples online, was pretty straightforward, but then I'm running into an error that I can't figure out. Here's the code I'm using (has been modified slightly for brevity):

<%@ 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);):

I keep getting the following error at line 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) 声明如下:

But I've seen many examples online doing things exactly as I've done them. I also ran into this article (https://msdn.microsoft.com/en-us/library/jj157089(v=vs.110).aspx) that states the following:

在 WIF 3.5 中,所有 WIF 类都包含在Microsoft.IdentityModel 程序集(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).

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).

WIF 3.5 类都包含在其中一个Microsoft.IdentityModel 命名空间;例如,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 中删除.

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 框架 4.5.1,因为 JWT 库需要它.除此之外,我不知道还能去哪里.

I tried for debugging sake to switch to use the Microsoft.* namespace for the SecurityTokenDescriptor, and then I get another series of errors saying TokenIssuerName, AppliesToAddress, and Lifetime aren't valid properties for that class. Yet when I look at the docs online, seems like those properties do exist on Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor. Yet in my Visual Studio, when I do Go to Definition for that class, they're not there, leading me to believe that there's some kind of configuration issue in my Visual Studio. In my package manager, it shows I have Microsoft.IdentityModel.Tokens v5.0.0 installed. I also changed the project to .NET framework 4.5.1 since the JWT library requires it. Beyond that, I don't know where else to look.

推荐答案

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

I ran into a similar situation with the OpenID Connect library when I upgraded, which previously was in the Microsoft.IdentityModel.Protocol.Extensions package (which depended on 4.0.2 of the JWT package) but now is Microsoft.IdentityModel.Protocols.OpenIdConnect which depends on 2.0.0 of Microsoft.IdentityModel.Protocols (which depends on 5.0.0 of the JWT package).

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

Remove any of your Microsoft.IdentityModel* and System.IdentityModel* packages, and install only the latest (5.0.0) System.IdentityModel.Tokens.Jwt package which depends on Microsoft.IdentityModel.Tokens.

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

You'll want using statements for these namespaces:

  • Microsoft.IdentityModel.Tokens(但不是 System.IdentityModel.Tokens)
  • System.IdentityModel.Tokens.Jwt
  • System.Security.Claims

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

Microsoft has simplified some of the parameters to be more like what you would expect from other platforms' JWT libraries, so the SecurityTokenDescriptor properties are a little different:

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.

Note that SecurityAlgorithms.HmacSha256 is a string constant for "HS256", just like you'd use in most other libraries. Using the above code plus the example in your question, you should be able to generate a valid JWT.

这篇关于尝试使用 .NET JWT 库生成令牌时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:.NetCore JwtBearerAuthentication 不拒绝过期令牌 下一篇:如何在 asp.net core 2.2 中实现 Cookie 基本身份验证和 jwt?

相关文章