Настройка проверки токена носителя JWT с использованием открытого ключа безопасности в .NET Core

Мое веб-приложение - это своего рода оболочка для какой-то сторонней службы. Эта сторонняя служба использует аутентификацию на носителе JWT для доступа к своим конечным точкам WebAPI. Токены зашифрованы с помощью алгоритма RS256 (асимметричный).

У меня есть открытый ключ для проверки подписи токенов на моей стороне. Проверить подпись на сайте jwt.io легко (просто вставьте токен и открытый ключ в текстовые поля). Но как мне настроить TokenValidationParameters, чтобы токены проверялись автоматически с использованием указанного открытого ключа?

Фрагмент кода AddAuthentication:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters.ValidateIssuer = true;
    options.TokenValidationParameters.ValidIssuer = "iss";
    options.TokenValidationParameters.ValidateIssuerSigningKey = true;
    options.TokenValidationParameters.IssuerSigningKey = SomeCodeToGenerateSecurityKeyUsingPublicKeyOnly("-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----");
    options.TokenValidationParameters.ValidateAudience = false;
    options.TokenValidationParameters.ValidateLifetime = true;
    options.TokenValidationParameters.ClockSkew = TimeSpan.Zero;
});

services.AddAuthorization(options =>
{
    options.AddPolicy("Bearer",
        new AuthorizationPolicyBuilder(new string[] { JwtBearerDefaults.AuthenticationScheme })
            .RequireAuthenticatedUser()
            .Build()
    );
});

Я не могу просто использовать класс SymmetricSecurityKey вот так:

options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("..."));

из-за асимметричного шифрования. В этом случае возникает исключение:

IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.SymmetricSecurityKey , KeyId: 
'.
Exceptions caught:
 ''.
token: '{"alg":"RS256","typ":"JWT"}....

person IDizor    schedule 05.04.2018    source источник


Ответы (1)


Хорошо, в конце концов мне удалось следующее решение. Объект RsaSecurityKey делает то, что я искал:

byte[] publicKeyBytes = Convert.FromBase64String("public_key_without_header_and_footer");
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)PublicKeyFactory.CreateKey(publicKeyBytes);
RSAParameters rsaParameters = new RSAParameters
{
    Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned(),
    Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned(),
};

......

options.TokenValidationParameters.IssuerSigningKey = new RsaSecurityKey(rsaParameters);

Я не уверен, что это лучшее решение, но пока у меня нет другого.

person IDizor    schedule 06.04.2018
comment
Что такое PublicKeyFactory? - person Alexey.Petriashev; 06.06.2018
comment
PublicKeyFactory находится в пространстве имен Org.BouncyCastle.Security из пакета Nuget BouncyCastle.NetCore. - person IDizor; 08.10.2018