尝试使用.NET JWT库

时间:2016-07-06 18:34:00

标签: c# asp.net jwt

我正在尝试使用包System.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.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)。

     

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。

我试图为了调试而转而使用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库需要它。除此之外,我不知道还能在哪里看。

1 个答案:

答案 0 :(得分:32)

我在升级时遇到了与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

您希望使用这些命名空间的语句:

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

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是&#34; HS256&#34;的字符串常量,就像您在大多数其他库中使用一样。使用上面的代码加上你问题中的例子,你应该能够生成一个有效的JWT。