use of org.opensaml.common.SAMLException in project cool-jconon by consiglionazionaledellericerche.
the class SPIDIntegrationService method validateAssertion.
private void validateAssertion(Response response, SPIDRequest spidRequest) throws SAMLException {
if (response.getAssertions().size() != 1) {
throw new SAMLException("The response doesn't contain exactly 1 assertion");
}
Assertion assertion = response.getAssertions().stream().findFirst().orElseThrow(() -> new SAMLException("The response doesn't contain exactly 1 assertion"));
Optional.ofNullable(assertion.getSubject()).orElseThrow(() -> new SAMLException("Assertion :: Subject not specified!"));
Optional.ofNullable(assertion.getSubject().getNameID()).orElseThrow(() -> new SAMLException("Assertion :: The NameID value is missing from the SAML response; this is likely an IDP configuration issue!"));
final String assertionId = Optional.ofNullable(assertion.getID()).filter(s -> s.length() > 0).orElseThrow(() -> new SAMLException("Assertion :: ID not specified!"));
final SAMLVersion samlVersion = Optional.ofNullable(assertion.getVersion()).orElseThrow(() -> new SAMLException("Assertion :: Version not specified!"));
if (samlVersion.getMajorVersion() != 2 || samlVersion.getMinorVersion() != 0) {
throw new SAMLException("Assertion :: Version is not correct!");
}
final DateTime issueInstant = Optional.ofNullable(assertion.getIssueInstant()).orElseThrow(() -> new SAMLException("Assertion :: IssueInstant not specified!"));
if (!spidRequest.getIssueIstant().isBefore(issueInstant)) {
throw new SAMLException("Assertion :: IssueInstant is before " + spidRequest.getIssueIstant().toString());
}
final AuthnStatement authnStatement = assertion.getAuthnStatements().stream().findAny().orElseThrow(() -> new SAMLException("Assertion :: AuthnStatements is not present!"));
final Optional<String> optionalAuthnContextClassRef = Optional.ofNullable(authnStatement.getAuthnContext()).flatMap(authnContext -> Optional.ofNullable(authnContext.getAuthnContextClassRef())).flatMap(authnContextClassRef -> Optional.ofNullable(authnContextClassRef.getAuthnContextClassRef()));
if (!optionalAuthnContextClassRef.filter(s -> idpConfiguration.getSpidProperties().getAuthnContextClassRef().contains(s)).isPresent()) {
throw new SAMLException("Assertion :: AuthnContextClassRef is not correct!");
}
final SubjectConfirmation subjectConfirmation = assertion.getSubject().getSubjectConfirmations().stream().findFirst().orElseThrow(() -> new SAMLException("Assertion :: SubjectConfirmation not specified!"));
Optional.ofNullable(subjectConfirmation.getMethod()).filter(s -> s.equalsIgnoreCase(SubjectConfirmation.METHOD_BEARER)).orElseThrow(() -> new SAMLException("Assertion :: SubjectConfirmation Method is not correct!"));
final SubjectConfirmationData subjectConfirmationData = Optional.ofNullable(subjectConfirmation).flatMap(subjectConfirmation1 -> Optional.ofNullable(subjectConfirmation1.getSubjectConfirmationData())).orElseThrow(() -> new SAMLException("Assertion :: SubjectConfirmationData not specified!"));
Optional.ofNullable(subjectConfirmationData.getRecipient()).filter(s -> s.equalsIgnoreCase(idpConfiguration.getSpidProperties().getDestination())).orElseThrow(() -> new SAMLException("Assertion :: SubjectConfirmationData -> Recipient is not correct!"));
Optional.ofNullable(subjectConfirmationData.getInResponseTo()).filter(s -> s.equalsIgnoreCase(spidRequest.getId())).orElseThrow(() -> new SAMLException("Assertion :: SubjectConfirmationData -> InResponseTo is not correct!"));
Optional.ofNullable(subjectConfirmationData.getNotOnOrAfter()).filter(dateTime -> dateTime.isAfter(spidRequest.getIssueIstant())).orElseThrow(() -> new SAMLException("Assertion :: SubjectConfirmationData -> NotOnOrAfter is not correct!"));
Optional.ofNullable(assertion.getIssuer()).filter(issuer -> issuer.getValue().equalsIgnoreCase(spidRequest.getIssuer())).orElseThrow(() -> new SAMLException("Assertion :: Issuer is not correct!"));
if (idpConfiguration.getSpidProperties().getValidateIssuerFormat()) {
Optional.ofNullable(assertion.getIssuer().getFormat()).filter(format -> format.equalsIgnoreCase(NameIDType.ENTITY)).orElseThrow(() -> new SAMLException("Assertion :: Issuer -> Format is not correct!"));
}
enforceConditions(assertion.getConditions(), spidRequest);
}
use of org.opensaml.common.SAMLException in project cool-jconon by consiglionazionaledellericerche.
the class SPIDIntegrationService method idpResponse.
public String idpResponse(String samlResponse) throws SAMLException, AuthenticationException {
Response response = decodeAndValidateSamlResponse(samlResponse);
final Map<String, String> collect = response.getAssertions().stream().map(Assertion::getAttributeStatements).flatMap(List<AttributeStatement>::stream).map(AttributeStatement::getAttributes).flatMap(List<Attribute>::stream).collect(HashMap::new, (m, attribute) -> m.put(attribute.getName(), getValue(attribute)), HashMap::putAll);
CMISUser cmisUser = new CMISUser();
cmisUser.setApplication(SPID);
cmisUser.setFirstName(collect.getOrDefault(idpConfiguration.getSpidProperties().getAttribute().getName(), null));
cmisUser.setLastName(collect.getOrDefault(idpConfiguration.getSpidProperties().getAttribute().getFamilyName(), null));
cmisUser.setDataDiNascita(Optional.ofNullable(collect.getOrDefault(idpConfiguration.getSpidProperties().getAttribute().getDateOfBirth(), null)).filter(s -> !s.isEmpty()).map(date -> {
try {
return Date.from(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
} catch (DateTimeParseException _ex) {
LOGGER.warn("Cannot format date of birth", _ex);
return null;
}
}).orElse(null));
cmisUser.setCodicefiscale(Optional.ofNullable(collect.getOrDefault(idpConfiguration.getSpidProperties().getAttribute().getFiscalNumber(), null)).map(cf -> cf.replaceAll("TINIT-", "")).orElse(null));
cmisUser.setSesso(collect.getOrDefault(idpConfiguration.getSpidProperties().getAttribute().getGender(), Optional.ofNullable(cmisUser.getCodicefiscale()).map(s -> Integer.valueOf(s.substring(9, 11)) > 40 ? "F" : "M").orElse(null)));
cmisUser.setEmail(collect.getOrDefault(idpConfiguration.getSpidProperties().getAttribute().getEmail(), " "));
String userName = normalize(Optional.ofNullable(cmisUser.getFirstName()).map(String::trim).filter(s -> !s.isEmpty()).orElseThrow(() -> new SAMLException("First Name cannot be empty"))).toLowerCase().concat("-").concat(normalize(Optional.ofNullable(cmisUser.getLastName()).map(String::trim).filter(s -> !s.isEmpty()).orElseThrow(() -> new SAMLException("Last Name cannot be empty"))).toLowerCase());
Optional<CMISUser> userByCodiceFiscale = Optional.ofNullable(userService.findUserByCodiceFiscale(cmisUser.getCodicefiscale(), cmisService.getAdminSession(), userName));
if (userByCodiceFiscale.isPresent()) {
if (!Optional.ofNullable(userByCodiceFiscale.get().getEmail()).equals(Optional.ofNullable(cmisUser.getEmail())) && Optional.ofNullable(userByCodiceFiscale.get().getApplication()).filter(s -> s.equalsIgnoreCase(SPID)).isPresent()) {
cmisUser.setUserName(userByCodiceFiscale.get().getUserName());
userByCodiceFiscale = Optional.ofNullable(userService.updateUser(cmisUser));
}
return createTicketForUser(userByCodiceFiscale.get());
} else {
// Verifico se l'utenza ha lo stesso codice fiscale
try {
Optional<CMISUser> cmisUser2 = Optional.ofNullable(userService.loadUserForConfirm(userName)).filter(cmisUser1 -> cmisUser1.getCodicefiscale().equalsIgnoreCase(cmisUser.getCodicefiscale()));
if (cmisUser2.isPresent()) {
if (!Optional.ofNullable(cmisUser2.get().getEmail()).equals(Optional.ofNullable(cmisUser.getEmail())) && Optional.ofNullable(cmisUser2.get().getApplication()).filter(s -> s.equalsIgnoreCase(SPID)).isPresent()) {
cmisUser.setUserName(cmisUser2.get().getUserName());
cmisUser2 = Optional.ofNullable(userService.updateUser(cmisUser));
}
return createTicketForUser(cmisUser2.get());
}
} catch (CoolUserFactoryException _ex) {
LOGGER.trace("SPID Username {} not found", userName);
}
if (!userService.isUserExists(userName)) {
cmisUser.setUserName(userName);
} else {
for (int i = 1; i < 20; i++) {
final String concatUsername = userName.concat("0").concat(String.valueOf(i));
if (!userService.isUserExists(concatUsername)) {
cmisUser.setUserName(concatUsername);
break;
}
}
}
final CMISUser user = userService.createUser(cmisUser);
userService.enableAccount(user.getUserName());
return createTicketForUser(user);
}
}
use of org.opensaml.common.SAMLException in project cloud-pipeline by epam.
the class OptionalSAMLLogoutFilter method processLogout.
/**
* In case request parameter of name "local" is set to true or there is no authenticated user
* only local logout will be performed and user will be redirected to the success page.
* Otherwise global logout procedure is initialized.
*
* @param request http request
* @param response http response
* @param chain chain
* @throws IOException error
* @throws ServletException error
*/
public void processLogout(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
if (requiresLogout(request, response)) {
try {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && isGlobalLogout(request, auth)) {
Assert.isInstanceOf(SAMLCredential.class, auth.getCredentials(), "Authentication object doesn't contain SAML credential, cannot perform global logout");
// Terminate the session first
for (LogoutHandler handler : globalHandlers) {
handler.logout(request, response, auth);
}
// Notify session participants using SAML Single Logout profile
SAMLCredential credential = (SAMLCredential) auth.getCredentials();
request.setAttribute(SAMLConstants.LOCAL_ENTITY_ID, credential.getLocalEntityID());
request.setAttribute(SAMLConstants.PEER_ENTITY_ID, credential.getRemoteEntityID());
SAMLMessageContext context = contextProvider.getLocalAndPeerEntity(request, response);
try {
profile.sendLogoutRequest(context, credential);
samlLogger.log(SAMLConstants.LOGOUT_REQUEST, SAMLConstants.SUCCESS, context);
} catch (MetadataProviderException e) {
logger.debug(e.getMessage(), e);
super.doFilter(request, response, chain);
}
} else {
super.doFilter(request, response, chain);
}
} catch (SAMLException e) {
logger.debug("Error initializing global logout", e);
throw new ServletException("Error initializing global logout", e);
} catch (MetadataProviderException e) {
logger.debug("Error processing metadata", e);
throw new ServletException("Error processing metadata", e);
} catch (MessageEncodingException e) {
logger.debug("Error encoding outgoing message", e);
throw new ServletException("Error encoding outgoing message", e);
}
} else {
chain.doFilter(request, response);
}
}
use of org.opensaml.common.SAMLException in project cloud-pipeline by epam.
the class SAMLProxyAuthenticationProvider method authenticate.
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
SAMLProxyAuthentication auth = (SAMLProxyAuthentication) authentication;
List<ExternalServiceEndpoint> externalServices = preferenceManager.getPreference(SYSTEM_EXTERNAL_SERVICES_ENDPOINTS);
if (CollectionUtils.isEmpty(externalServices)) {
throw new AuthenticationServiceException(messageHelper.getMessage(MessageConstants.ERROR_PROXY_SECURITY_CONFIG_MISSING));
}
if (StringUtils.isNotBlank(auth.getRawSamlResponse())) {
try {
Response decoded = CustomSamlClient.decodeSamlResponse(auth.getRawSamlResponse());
String endpointId = // cut out SSO endpoint
decoded.getDestination().substring(0, decoded.getDestination().length() - CustomSamlClient.SSO_ENDPOINT.length());
Optional<ExternalServiceEndpoint> endpointOpt = externalServices.stream().filter(e -> e.getEndpointId().equals(endpointId)).findFirst();
if (endpointOpt.isPresent()) {
return validateAuthentication(auth, decoded, endpointId, endpointOpt.get());
} else {
throw new AuthenticationServiceException("Authentication error: unexpected external service");
}
} catch (SAMLException e) {
throw new AuthenticationServiceException("Authentication error: ", e);
}
} else {
throw new AuthenticationServiceException("Authentication error: missing SAML token");
}
}
use of org.opensaml.common.SAMLException in project cloud-pipeline by epam.
the class CustomSamlClient method validateSignature.
private void validateSignature(Response response) throws SAMLException {
Signature responseSignature = response.getSignature();
Signature assertionSignature = response.getAssertions().get(0).getSignature();
if (responseSignature == null && assertionSignature == null) {
throw new SAMLException("No signature is present in either response or assertion");
}
if (responseSignature != null && !validate(responseSignature)) {
throw new SAMLException("The response signature is invalid");
}
if (assertionSignature != null && !validate(assertionSignature)) {
throw new SAMLException("The assertion signature is invalid");
}
}
Aggregations