Ошибка при попытке создания токена с использованием библиотеки .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, когда я делаю Go to Definition для этого класса, их там нет, и я полагаю, что в моей Visual Studio есть какая-то проблема с конфигурацией. В моем диспетчере пакетов он показывает, что у меня установлен Microsoft.IdentityModel.Tokens v5.0.0. Я также сменил проект на .NET framework 4.5.1, поскольку это требует библиотека JWT. Помимо этого, я не знаю, где еще искать.

Ответ 1

Я столкнулся с аналогичной ситуацией с библиотекой OpenID Connect при обновлении, которая ранее находилась в пакете Microsoft.IdentityModel.Protocol.Extensions (который зависел от 4.0.2 пакета JWT), но теперь это Microsoft.IdentityModel.Protocols.OpenIdConnect, которое зависит от 2.0. 0 of Microsoft.IdentityModel.Protocols (который зависит от 5.0.0 пакета JWT).

Удалите все ваши пакеты 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 является строковой константой для "HS256", как и в большинстве других библиотек. Используя приведенный выше код плюс пример в вашем вопросе, вы должны иметь возможность генерировать действительный JWT.