use of com.nimbusds.jose.proc.JWSKeySelector in project ddf by codice.
the class OidcTokenValidator method validateAccessTokenSignature.
/**
* Validates an access token's signature
*
* @param accessToken - the token to validate
* @param idToken - the corresponding ID token or null if one is not available. If an ID token is
* provided, the signature algorithm in the ID token is used. Otherwise the Algorithm provided
* in the header of the access token is used.
* @param resourceRetriever - resource retriever
* @param metadata - OIDC metadata
*/
private static void validateAccessTokenSignature(AccessToken accessToken, JWT idToken, ResourceRetriever resourceRetriever, OIDCProviderMetadata metadata) throws OidcValidationException {
try {
ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor();
JWKSource keySource = new RemoteJWKSet(metadata.getJWKSetURI().toURL(), resourceRetriever);
// Get signature algorithm, if ID token is given get algorithm from ID Token otherwise
// get algorithm from access token header
Algorithm expectedAlgorithm;
if (idToken == null || idToken.getHeader().getAlgorithm() == Algorithm.NONE) {
String accessTokenString = accessToken.getValue();
Base64URL header = new Base64URL(accessTokenString.substring(0, accessTokenString.indexOf('.')));
JSONObject jsonObject = JSONObjectUtils.parse(header.decodeToString());
expectedAlgorithm = Header.parseAlgorithm(jsonObject);
} else {
expectedAlgorithm = idToken.getHeader().getAlgorithm();
}
if (expectedAlgorithm == Algorithm.NONE) {
LOGGER.error("Error validating access token. Access token was not signed.");
throw new OidcValidationException("Error validating access token. Access token was not signed.");
}
JWSAlgorithm expectedJWSAlgorithm = new JWSAlgorithm(expectedAlgorithm.getName(), expectedAlgorithm.getRequirement());
JWSKeySelector keySelector = new JWSVerificationKeySelector(expectedJWSAlgorithm, keySource);
jwtProcessor.setJWSKeySelector(keySelector);
jwtProcessor.process(accessToken.getValue(), null);
} catch (Exception e) {
LOGGER.error(ACCESS_VALIDATION_ERR_MSG, e);
throw new OidcValidationException(ACCESS_VALIDATION_ERR_MSG, e);
}
}
use of com.nimbusds.jose.proc.JWSKeySelector in project ddf by codice.
the class OidcTokenValidator method validateUserInfoIdToken.
/**
* Validates id tokens received from the userinfo endpoint.
*
* <ul>
* <li>If the ID token is not signed, validation is ignored
* <li>If the ID token is signed
* <ul>
* <li>If the userinfo signing algorithms are listed in the metadata, we use that
* information along with the header attributes to validate the token
* <li>If the userinfo signing algorithms are NOT listed in the metadata, we just use the
* header attributes to validate the token
* </ul>
*
* @param idToken - id token to validate
* @param resourceRetriever - resource retriever
* @param metadata - OIDC metadata
*/
public static void validateUserInfoIdToken(JWT idToken, ResourceRetriever resourceRetriever, OIDCProviderMetadata metadata) throws OidcValidationException {
if (metadata == null) {
LOGGER.debug("Oidc metadata is null. Unable to validate userinfo id token.");
return;
}
if (resourceRetriever == null) {
resourceRetriever = new DefaultResourceRetriever();
}
try {
if (!(idToken instanceof SignedJWT)) {
LOGGER.info("ID token received from the userinfo endpoint was not signed.");
return;
}
JWKSource jwkSource = new RemoteJWKSet(metadata.getJWKSetURI().toURL(), resourceRetriever);
SignedJWT signedJWT = ((SignedJWT) idToken);
JWSAlgorithm jwsAlgorithm = signedJWT.getHeader().getAlgorithm();
List<JWSAlgorithm> userInfoSigAlgList = metadata.getUserInfoJWSAlgs();
if (userInfoSigAlgList.isEmpty()) {
LOGGER.warn("A JWS algorithm was not listed in the OpenID Connect provider metadata. " + "Using JWS algorithm specified in the header.");
} else {
if (!userInfoSigAlgList.contains(jwsAlgorithm)) {
LOGGER.error("The signature algorithm of the id token do not match the expected ones.");
throw new OidcValidationException("The signature algorithm of the id token do not match the expected ones.");
}
}
JWSKeySelector jwsKeySelector = new JWSVerificationKeySelector(jwsAlgorithm, jwkSource);
JWSVerifierFactory jwsVerifierFactory = new DefaultJWSVerifierFactory();
List<? extends Key> keyCandidates = jwsKeySelector.selectJWSKeys(signedJWT.getHeader(), null);
if (keyCandidates == null || keyCandidates.isEmpty()) {
throw new OidcValidationException("Error Validating userinfo ID token. No matching key(s) found");
}
ListIterator<? extends Key> it = keyCandidates.listIterator();
while (it.hasNext()) {
JWSVerifier verifier = jwsVerifierFactory.createJWSVerifier(signedJWT.getHeader(), it.next());
if (verifier == null) {
continue;
}
final boolean validSignature = signedJWT.verify(verifier);
if (validSignature) {
return;
}
if (!it.hasNext()) {
throw new OidcValidationException("Error Validating userinfo ID token. Invalid signature");
}
}
throw new OidcValidationException("Error Validating userinfo ID token. No matching verifier(s) found");
} catch (Exception e) {
LOGGER.error(ID_VALIDATION_ERR_MSG, e);
throw new OidcValidationException(ID_VALIDATION_ERR_MSG, e);
}
}
Aggregations