#spring-security #jwt #public-key
#spring-безопасность #jwt #открытый ключ
Вопрос:
Я использую spring security, и я создал средство проверки JWT. Пока он проверяет только время истечения срока действия.
Проблема в том, что я предоставляю два разных API, и вызывающие пользователи также используют разные открытые / закрытые ключи для генерации jwt (ов), которыми я управляю, что означает, что у меня есть два разных открытых ключа, чтобы иметь возможность проверять соответствующие им JWT.
Каков наилучший способ сохранить только одну функцию, которая проверяет токены, но которая также переключается между открытыми ключами?
пример :
public class JwtControlValid {
@Value("${public.key.A}") // from application.properties
private String pubKeyA;
@Value("${public.key.B}")
private String pubKeyB;
private RSAPublicKey getPubKey() {
try {
KeyFactory kf = KeyFactory.getInstance("RSA");
// if(caller A)
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(pubKeyA));
// if (caller B)
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(pubKeyB));
RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(keySpecX509);
return pubKey;
}catch ...
и еще одна функция, которая использует первую, чтобы указать, является ли true или false :
public boolean isJwtValid(String jwt) {
try {
Jwts.parser().setSigningKey(getPublicKey()).parseClaimsJws(jwt);
return true;
} catch ....
return false;
Оба открытых ключа RSA public keys
Есть ли простой способ переключения между открытыми ключами в зависимости от jwt, который я получаю?
Комментарии:
1. обычно
kid
для этого используется утверждение идентификатора ключа. Каждому ключу присваивается идентификатор ключа, и токен имеет претензию с правильным идентификатором.
Ответ №1:
Проблема в том, что я предоставляю два разных API, и вызывающие пользователи также используют разные открытые / закрытые ключи для генерации jwt (ов), которыми я управляю, что означает, что у меня есть два разных открытых ключа, чтобы иметь возможность проверять соответствующие им JWT.
Да, это проблема и не является стандартом. Наличие открытых ключей для каждого клиента плохо масштабируется и, как правило, не поддерживается.
Spring из коробки поддерживает доверие к одному асимметричному ключу, но не к нескольким, потому что это не стандарт, и я не рекомендую этот подход.
Если вы хотите поддерживать несколько ключей, вам следует вместо этого использовать JWKs
несколько ключей, которые предоставляет служба выдачи.
Что это в основном означает, что эмитент (сервер / служба), который выдает ваши токены, имеет конечную точку, из которой все серверы ресурсов могут извлекать открытые ключи, необходимые для проверки токенов.
Преимущества в том, что вы можете вращать ключи, вы можете проверять несколько JWK, это масштабируемо и безопасно и т.д.
Если вы все еще хотите пойти по своему пути, который я настоятельно не рекомендую, вы можете, например, реализовать два JwtAuthenticationProvider
, используя его интерфейс.
Вы можете решить, какой из них использовать, реализовав a AuthenticationManagerResolver
.
Я бы настоятельно рекомендовал вам прочитать обо всем потоке JWT в официальных документах spring security и использовать Nimbus
то, что входит в spring security, вместо JJwt
того, чтобы использовать просто дополнительную ненужную зависимость.
Я просто хочу добавить, что написание пользовательской безопасности никогда не бывает хорошим, и все, что требуется, — это одна ошибка в вашем пользовательском коде безопасности, и вся ваша безопасность может быть бесполезной. Вот почему существуют стандарты, RFC и установленные потоки. Чтобы избежать пользовательских решений безопасности.