use of org.keycloak.jose.JOSE in project keycloak by keycloak.
the class DefaultTokenManager method decodeClientJWT.
@Override
public <T> T decodeClientJWT(String jwt, ClientModel client, BiConsumer<JOSE, ClientModel> jwtValidator, Class<T> clazz) {
if (jwt == null) {
return null;
}
JOSE joseToken = JOSEParser.parse(jwt);
jwtValidator.accept(joseToken, client);
if (joseToken instanceof JWE) {
try {
Optional<KeyWrapper> activeKey;
String kid = joseToken.getHeader().getKeyId();
Stream<KeyWrapper> keys = session.keys().getKeysStream(session.getContext().getRealm());
if (kid == null) {
activeKey = keys.filter(k -> KeyUse.ENC.equals(k.getUse()) && k.getPublicKey() != null).sorted(Comparator.comparingLong(KeyWrapper::getProviderPriority).reversed()).findFirst();
} else {
activeKey = keys.filter(k -> KeyUse.ENC.equals(k.getUse()) && k.getKid().equals(kid)).findAny();
}
JWE jwe = JWE.class.cast(joseToken);
Key privateKey = activeKey.map(KeyWrapper::getPrivateKey).orElseThrow(() -> new RuntimeException("Could not find private key for decrypting token"));
jwe.getKeyStorage().setDecryptionKey(privateKey);
byte[] content = jwe.verifyAndDecodeJwe().getContent();
try {
JOSE jws = JOSEParser.parse(new String(content));
if (jws instanceof JWSInput) {
jwtValidator.accept(jws, client);
return verifyJWS(client, clazz, (JWSInput) jws);
}
} catch (Exception ignore) {
// try to decrypt content as is
}
return JsonSerialization.readValue(content, clazz);
} catch (IOException cause) {
throw new RuntimeException("Failed to deserialize JWT", cause);
} catch (JWEException cause) {
throw new RuntimeException("Failed to decrypt JWT", cause);
}
}
return verifyJWS(client, clazz, (JWSInput) joseToken);
}
Aggregations