JwtBearerAssertionAuthenticationToken jwtAuth = (JwtBearerAssertionAuthenticationToken)authentication;
try {
ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getClientId());
JWT jwt = jwtAuth.getJwt();
ReadOnlyJWTClaimsSet jwtClaims = jwt.getJWTClaimsSet();
// check the signature with nimbus
if (jwt instanceof SignedJWT) {
SignedJWT jws = (SignedJWT)jwt;
JWSAlgorithm alg = jws.getHeader().getAlgorithm();
if (client.getTokenEndpointAuthSigningAlg() != null &&
!client.getTokenEndpointAuthSigningAlg().equals(alg)) {
throw new InvalidClientException("Client's registered request object signing algorithm (" + client.getRequestObjectSigningAlg() + ") does not match request object's actual algorithm (" + alg.getName() + ")");
}
if (client.getTokenEndpointAuthMethod() == null ||
client.getTokenEndpointAuthMethod().equals(AuthMethod.NONE) ||
client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC) ||
client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST)) {
// this client doesn't support this type of authentication
throw new AuthenticationServiceException("Client does not support this authentication method.");
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) &&
(alg.equals(JWSAlgorithm.RS256)
|| alg.equals(JWSAlgorithm.RS384)
|| alg.equals(JWSAlgorithm.RS512))) {
JwtSigningAndValidationService validator = validators.getValidator(client.getJwksUri());
if (validator == null) {
throw new AuthenticationServiceException("Unable to create signature validator for client's JWKS URI: " + client.getJwksUri());
}
if (!validator.validateSignature(jws)) {
throw new AuthenticationServiceException("Signature did not validate for presented JWT authentication.");
}
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT) &&
(alg.equals(JWSAlgorithm.HS256)
|| alg.equals(JWSAlgorithm.HS384)
|| alg.equals(JWSAlgorithm.HS512))) {
// it's HMAC, we need to make a validator based on the client secret
JwtSigningAndValidationService validator = symmetricCacheService.getSymmetricValidtor(client);
if (validator == null) {
throw new AuthenticationServiceException("Unable to create signature validator for client's secret: " + client.getClientSecret());
}
if (!validator.validateSignature(jws)) {
throw new AuthenticationServiceException("Signature did not validate for presented JWT authentication.");
}
}
}
// check the issuer
if (jwtClaims.getIssuer() == null) {
throw new AuthenticationServiceException("Assertion Token Issuer is null");
} else if (!jwtClaims.getIssuer().equals(client.getClientId())){
throw new AuthenticationServiceException("Issuers do not match, expected " + client.getClientId() + " got " + jwtClaims.getIssuer());
}
// check expiration
if (jwtClaims.getExpirationTime() == null) {
throw new AuthenticationServiceException("Assertion Token does not have required expiration claim");
} else {
// it's not null, see if it's expired
Date now = new Date(System.currentTimeMillis() - (timeSkewAllowance * 1000));
if (now.after(jwtClaims.getExpirationTime())) {
throw new AuthenticationServiceException("Assertion Token is expired: " + jwtClaims.getExpirationTime());
}
}
// check not before
if (jwtClaims.getNotBeforeTime() != null) {
Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000));
if (now.before(jwtClaims.getNotBeforeTime())){
throw new AuthenticationServiceException("Assertion Token not valid untill: " + jwtClaims.getNotBeforeTime());
}
}
// check issued at
if (jwtClaims.getIssueTime() != null) {
// since it's not null, see if it was issued in the future
Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000));
if (now.before(jwtClaims.getIssueTime())) {
throw new AuthenticationServiceException("Assertion Token was issued in the future: " + jwtClaims.getIssueTime());
}
}
// check audience
if (jwtClaims.getAudience() == null) {
throw new AuthenticationServiceException("Assertion token audience is null");
} else if (!(jwtClaims.getAudience().contains(config.getIssuer()) || jwtClaims.getAudience().contains(config.getIssuer() + "token"))) {
throw new AuthenticationServiceException("Audience does not match, expected " + config.getIssuer() + " or " + (config.getIssuer() + "token") + " got " + jwtClaims.getAudience());
}
// IFF we managed to get all the way down here, the token is valid
return new JwtBearerAssertionAuthenticationToken(client.getClientId(), jwt, client.getAuthorities());
} catch (InvalidClientException e) {
throw new UsernameNotFoundException("Could not find client: " + jwtAuth.getClientId());
} catch (ParseException e) {