use of io.jans.ca.server.HttpException in project jans by JanssenProject.
the class Validator method validateIdToken.
public void validateIdToken(String nonce) {
try {
final String issuer = idToken.getClaims().getClaimAsString(JwtClaimName.ISSUER);
final String sub = idToken.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER);
final String nonceFromToken = idToken.getClaims().getClaimAsString(JwtClaimName.NONCE);
final String clientId = rp.getClientId();
// validate nonce
if (configuration.getFapiEnabled() && Strings.isNullOrEmpty(nonceFromToken)) {
LOG.error("Nonce is missing from id_token.");
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_NO_NONCE);
}
if (!Strings.isNullOrEmpty(nonce) && !nonceFromToken.endsWith(nonce)) {
LOG.error("ID Token has invalid nonce. Expected nonce: " + nonce + ", nonce from token is: " + nonceFromToken);
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_BAD_NONCE);
}
// validate audience
validateAudience(idToken, clientId);
// validate subject identifier
if (Strings.isNullOrEmpty(sub)) {
LOG.error("ID Token is missing `sub` value.");
throw new HttpException(ErrorResponseCode.NO_SUBJECT_IDENTIFIER);
}
// validate id_token issued at date
final Date issuedAt = idToken.getClaims().getClaimAsDate(JwtClaimName.ISSUED_AT);
if (issuedAt == null) {
LOG.error("`ISSUED_AT` date is either invalid or missing from `ID_TOKEN`.");
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_ISSUED_AT);
}
final Date now = new Date();
if (configuration.getFapiEnabled() && TimeUnit.MILLISECONDS.toHours(now.getTime() - issuedAt.getTime()) > configuration.getIatExpirationInHours()) {
LOG.error("`ISSUED_AT` date too far in the past. iat : " + issuedAt + " now : " + now + ").");
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_OLD_ISSUED_AT);
}
// validate id_token expire date
final Date expiresAt = idToken.getClaims().getClaimAsDate(JwtClaimName.EXPIRATION_TIME);
if (expiresAt == null) {
LOG.error("EXPIRATION_TIME (`exp`) is either invalid or missing from `ID_TOKEN`.");
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_EXPIRATION_TIME);
}
if (now.after(expiresAt)) {
LOG.error("ID Token is expired. (" + expiresAt + " is before " + now + ").");
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_EXPIRED);
}
// 1. validate issuer
if (Strings.isNullOrEmpty(issuer)) {
LOG.error("Issuer (`iss`) claim is missing from id_token.");
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_NO_ISSUER);
}
if (!issuer.equals(discoveryResponse.getIssuer())) {
LOG.error("ID Token issuer is invalid. Token issuer: " + issuer + ", discovery issuer: " + discoveryResponse.getIssuer());
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_BAD_ISSUER);
}
// validate signature
final String algorithm = idToken.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM);
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.fromString(algorithm);
// validate algorithm
if (!Strings.isNullOrEmpty(rp.getIdTokenSignedResponseAlg()) && SignatureAlgorithm.fromString(rp.getIdTokenSignedResponseAlg()) != signatureAlgorithm) {
LOG.error("The algorithm used to sign the ID Token does not matches with `id_token_signed_response_alg` algorithm set during client registration.Expected: {}, Got: {}", rp.getIdTokenSignedResponseAlg(), algorithm);
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_INVALID_ALGORITHM);
}
if (signatureAlgorithm != SignatureAlgorithm.NONE) {
boolean signature = jwsSigner.validate(idToken);
if (!signature) {
LOG.error("ID Token signature is invalid.");
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_BAD_SIGNATURE);
}
}
} catch (HttpException e) {
throw e;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_UNKNOWN);
}
}
use of io.jans.ca.server.HttpException in project jans by JanssenProject.
the class GetIssuerOperation method getWebfingerResponse.
private static GetIssuerResponse getWebfingerResponse(String resource) {
try {
OpenIdConnectDiscoveryClient client = new OpenIdConnectDiscoveryClient(resource);
OpenIdConnectDiscoveryResponse response = client.exec();
if (response == null || Strings.isNullOrEmpty(response.getSubject()) || response.getLinks().isEmpty()) {
LOG.error("Error in fetching op discovery configuration response ");
throw new HttpException(ErrorResponseCode.FAILED_TO_GET_ISSUER);
}
GetIssuerResponse webfingerResponse = new GetIssuerResponse();
BeanUtils.copyProperties(webfingerResponse, response);
return webfingerResponse;
} catch (Exception e) {
LOG.error("Error in creating op discovery configuration response ", e);
throw new HttpException(ErrorResponseCode.FAILED_TO_GET_ISSUER);
}
}
use of io.jans.ca.server.HttpException in project jans by JanssenProject.
the class GetRequestObjectUriOperation method execute.
public IOpResponse execute(GetRequestObjectUriParams params) {
try {
validate(params);
final Rp rp = getRp();
SignatureAlgorithm algo = SignatureAlgorithm.fromString(params.getRequestObjectSigningAlg()) != null ? SignatureAlgorithm.fromString(params.getRequestObjectSigningAlg()) : SignatureAlgorithm.fromString(rp.getRequestObjectSigningAlg());
if (algo == null) {
LOG.error("`request_object_signing_alg` is required parameter in request. Please set this parameter if it is not set during client registration.");
throw new HttpException(ErrorResponseCode.INVALID_ALGORITHM);
}
Jwt unsignedJwt = createRequestObject(algo, rp, params);
// signing request object
Jwt signedJwt = getKeyGeneratorService().sign(unsignedJwt, rp.getClientSecret(), algo);
// setting request object in Expired Object
String requestUriId = UUID.randomUUID().toString();
getRequestObjectService().put(requestUriId, signedJwt.toString());
String requestUri = baseRequestUri(params.getRpHostUrl()) + requestUriId;
LOG.trace("RequestObject created successfully. request_uri : {} ", requestUri);
GetRequestObjectUriResponse response = new GetRequestObjectUriResponse();
response.setRequestUri(requestUri);
return response;
} catch (HttpException e) {
throw e;
} catch (Exception e) {
LOG.error("Error in creating `request_uri` response ", e);
}
throw new HttpException(ErrorResponseCode.FAILED_TO_GET_REQUEST_URI);
}
use of io.jans.ca.server.HttpException in project jans by JanssenProject.
the class GetUserInfoOperation method validateSubjectIdentifier.
public void validateSubjectIdentifier(String idToken, UserInfoResponse response) {
try {
boolean validateUserInfoWithIdToken = getConfigurationService().getConfiguration().getValidateUserInfoWithIdToken();
if (!validateUserInfoWithIdToken) {
return;
}
if (Strings.isNullOrEmpty(idToken)) {
return;
}
LOG.trace("Validating subject Identifier (`sub`) of userInfo response.");
String subjectIdentifier = response.getClaims().get("sub");
final Jwt jwtIdToken = Jwt.parse(idToken);
if (!jwtIdToken.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER).equals(subjectIdentifier)) {
LOG.error("UserInfo `sub` value does not matches with `sub` value of ID_TOKEN.\n ID_TOKEN `sub`: {} \n UserInfo `sub`: {} ", jwtIdToken.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER), subjectIdentifier);
throw new HttpException(ErrorResponseCode.INVALID_SUBJECT_IDENTIFIER);
}
} catch (HttpException e) {
throw e;
} catch (Exception e) {
LOG.error("Error in matching `sub` value of UserInfo with `sub` value of ID_TOKEN.", e);
throw new HttpException(ErrorResponseCode.FAILED_TO_VERIFY_SUBJECT_IDENTIFIER);
}
}
Aggregations