Я борюсь с реализацией (или пониманием) подписи ключей для аутентификации маркера на предъявителя JWT. И я надеюсь, что кто-то может мне помочь или объяснить мне, что я недопонимаю.
В течение последних нескольких недель я просканировал множество обучающих программ и сумел запустить пользовательский Auth-Controller, который выдает мои токены и сумел настроить аутентификацию на предъявителя JWT для проверки токенов в заголовке.
Он работает.
Моя проблема заключается в том, что все примеры и учебники генерируют случайные или незавершенные (эмитент) подписи ключей или используют жестко закодированные строки "пароль" или берут их из некоторого файла конфигурации (ищите "пароль" в образцах кода).
Что я имею в виду для настройки проверки (в StartUp.cs):
//using hardcoded "password"
SecurityKey key = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes("password"));
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "MyIssuer",
ValidateAudience = true,
ValidAudience = "MyAudience",
ValidateLifetime = true,
IssuerSigningKey = key
}
});
В AuthController, создающем токен:
//using hardcoded password
var signingKey = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes("password"));
SigningCredentials credentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken // Create the JWT and write it to a string
(
issuer: _jwtTokenSettings.Issuer,
audience: _jwtTokenSettings.Audience,
claims: claims,
notBefore: now,
expires: now.AddSeconds(_jwtTokenSettings.LifetimeInSeconds),
signingCredentials: credentials
);
В этот вопрос они использовали:
RSAParameters keyParams = RSAKeyUtils.GetRandomKey();
Мои (текущие) предположения заключались в том, что в процессе производства вы не должны использовать жестко заданные строки или строки из файлов конфигурации для ключей подписи маркера. Но вместо этого используйте некоторые файлы сертификатов??? Я не прав?
Итак, я попытался заменить строки сертификатом, который работает в контроллере auth:
//using a certificate file
X509Certificate2 cert = new X509Certificate2("MySelfSignedCertificate.pfx", "password");
X509SecurityKey key = new X509SecurityKey(cert);
SigningCredentials credentials = new SigningCredentials(key, "RS256");
var jwt = new JwtSecurityToken // Create the JWT and write it to a string
(
issuer: _jwtTokenSettings.Issuer,
audience: _jwtTokenSettings.Audience,
claims: claims,
notBefore: now,
expires: now.AddSeconds(_jwtTokenSettings.LifetimeInSeconds),
signingCredentials: credentials
);
Но не существует способа получить подтверждение с помощью сертификата.
X509Certificate2 cert = new X509Certificate2("MySelfSignedCertificate.pfx", "password");
SecurityKey key == // ??? how to get the security key from file (not necessarily pfx)
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "MyIssuer",
ValidateAudience = true,
ValidAudience = "MyAudience",
ValidateLifetime = true,
IssuerSigningKey = key
}
});
Я ошибаюсь, что должен использовать сертификаты для ключей подписи? Как еще я могу изменить ключи подписи в процессе производства, когда контроллер авторизации находится на другом сервере, чем потребительский/защищенный веб-api (может один раз, а не сейчас)?
Кажется, я тоже пропустил (необходимые шаги), чтобы получить ответ этого вопроса.
Теперь, когда я его запускал, я все еще не вижу смысла, если это так?
Примечательно: файл не найден (после развертывания на сервере)
Для всех тех, кто использует это, и он работает при запуске из Visual Studio, но после развертывания на сервере /azure он говорит "Файл не найден":
прочитайте и подтвердите этот вопрос: сертификат X509 не загружает файл закрытого ключа на сервер
Примечательно 2: на самом деле он не нужен для аутентификации на токенах
Открытый ключ не обязательно должен быть на стороне API. Он будет автоматически извлечен через конечную точку обнаружения сервера аутентификации.