Как настроить открытый ключ для проверки токенов JWT из Keycloak? - PullRequest
0 голосов
/ 29 ноября 2018

Я пишу бэкэнд-микросервис, который получает запросы от внешнего интерфейса с заголовком Authorisation: Bearer ..., с токеном, полученным из keycloak (который находится внутри контейнера докера).

Я получил открытый ключ RSA для проверки подписи этого токена в разделе «Настройки» раздела «Ключи», но кажется, что при перезапуске контейнера с keycloak он восстанавливает пару ключей, и мой открытый ключ устанавливается в конфигурации службыстановится недействительным.

Как правильно работать с открытым ключом RSA из keycloak?Есть ли способ настроить его для использования фиксированной пары ключей для области?Экспортируются ли ключи при экспорте областей?Или я должен получить открытый ключ из keycloak, используя url, такой как http://keycloak:8080/auth/realms/:realm_name:, что я предпочитаю не делать, потому что это добавляет зависимость между keycloak и backend.

1 Ответ

0 голосов
/ 13 июня 2019

Необходимо проверить подпись токена JWT на основе конечной точки сервера идентификации эмитента /.well-known/jwks.

1) Запросить конечную точку сервера идентификации эмитента /.well-known/jwks (JWKS означает набор веб-ключей JSON)

2) Из JWKS получить JWK (веб-ключ JSON) с тем же kid (идентификатор ключа) в качестве токена Bearer, который мы проверяем.Чтобы получить kid из вашего токена JWT, сначала расшифруйте его, используя инструмент отладчика jwt.io .

3) Пока токены, выданные сервером идентификации, проверяются асимметричнокриптографическим алгоритмом (например, RS256), мы можем проверить подпись только с помощью открытого ключа (поэтому вам не понадобится закрытый ключ)

4) открытый ключ можно получить из JWK (этоx5c запись в JWK JSON)

5) Проверьте подпись токена JWT Bearer с помощью этого открытого ключа.

Например, в Java вы можете проверить это следующим образом:

// verify JWT signature based on Access Identity's JWKS RSA public key (RS256)
try {

  Jwk jwk = new UrlJwkProvider(new URL(issuer + Constants.JWKS_ENDPOINT)).get(decodedJWT.getKeyId());
  final PublicKey publicKey = jwk.getPublicKey();

  if (!(publicKey instanceof RSAPublicKey)) {
    throw new IllegalArgumentException("Key with ID " + decodedJWT.getKeyId() + " was found in JWKS but is not a RSA-key.");
  }

  Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) publicKey, null);
  JWTVerifier verifier = JWT.require(algorithm)
      .withIssuer(issuer)
      .build(); //Reusable verifier instance

  verifier.verify(bearerToken);

  LOGGER.info("Token verified!");

} catch (Exception e) {
  LOGGER.error(e.getMessage());
  throw new InvalidAccessTokenException("JWTVerificationException - Invalid token signature.");
}
...