// Determine the transport mechanism
boolean isSecure = request.isSecure();
String loginType = determineLoginType(isSecure);
IDPWebRequestUtil webRequestUtil = new IDPWebRequestUtil(request, idpConfiguration, keyManager);
try {
samlDocumentHolder = webRequestUtil.getSAMLDocumentHolder(samlRequestMessage);
samlObject = samlDocumentHolder.getSamlObject();
if (!(samlObject instanceof RequestAbstractType)) {
throw logger.wrongTypeError(samlObject.getClass().getName());
}
// Get the SAML Request Message
RequestAbstractType requestAbstractType = (RequestAbstractType) samlObject;
String issuer = requestAbstractType.getIssuer().getValue();
if (samlRequestMessage == null)
throw logger.samlIDPValidationCheckFailed();
IssuerInfoHolder idpIssuer = new IssuerInfoHolder(getIdentityURL());
ProtocolContext protocolContext = new HTTPContext(request, response, getContext().getServletContext());
// Create the request/response
SAML2HandlerRequest saml2HandlerRequest = new DefaultSAML2HandlerRequest(protocolContext, idpIssuer.getIssuer(),
samlDocumentHolder, HANDLER_TYPE.IDP);
saml2HandlerRequest.setRelayState(relayState);
if (StringUtil.isNotNull(loginType)) {
saml2HandlerRequest.addOption(GeneralConstants.LOGIN_TYPE, loginType);
}
String assertionID = (String) session.getSession().getAttribute(GeneralConstants.ASSERTION_ID);
// Set the options on the handler request
Map<String, Object> requestOptions = new HashMap<String, Object>();
requestOptions.put(GeneralConstants.IGNORE_SIGNATURES, willIgnoreSignatureOfCurrentRequest(issuer));
requestOptions.put(GeneralConstants.SP_SSO_METADATA_DESCRIPTOR, spSSOMetadataMap.get(issuer));
requestOptions.put(GeneralConstants.ROLE_GENERATOR, roleGenerator);
requestOptions.put(GeneralConstants.CONFIGURATION, this.idpConfiguration);
requestOptions.put(GeneralConstants.SAML_IDP_STRICT_POST_BINDING, this.idpConfiguration.isStrictPostBinding());
requestOptions.put(GeneralConstants.SUPPORTS_SIGNATURES, this.idpConfiguration.isSupportsSignature());
if (assertionID != null)
requestOptions.put(GeneralConstants.ASSERTION_ID, assertionID);
if (this.keyManager != null) {
PublicKey validatingKey = getIssuerPublicKey(request, issuer);
requestOptions.put(GeneralConstants.SENDER_PUBLIC_KEY, validatingKey);
requestOptions.put(GeneralConstants.DECRYPTING_KEY, keyManager.getSigningKey());
}
// if this is a SAML AuthnRequest load the roles using the generator.
if (requestAbstractType instanceof AuthnRequestType) {
List<String> roles = roleGenerator.generateRoles(userPrincipal);
session.getSession().setAttribute(GeneralConstants.ROLES_ID, roles);
Map<String, Object> attribs = this.attribManager.getAttributes(
passUserPrincipalToAttributeManager == true
? request.getUserPrincipal()
: userPrincipal,
attributeKeys);
requestOptions.put(GeneralConstants.ATTRIBUTES, attribs);
}
if (auditHelper != null) {
requestOptions.put(GeneralConstants.AUDIT_HELPER, auditHelper);
requestOptions.put(GeneralConstants.CONTEXT_PATH, contextPath);
}
saml2HandlerRequest.setOptions(requestOptions);
SAML2HandlerResponse saml2HandlerResponse = new DefaultSAML2HandlerResponse();
Set<SAML2Handler> handlers = chain.handlers();
logger.trace("Handlers are=" + handlers);
// the trusted domains is done by a handler
// webRequestUtil.isTrusted(issuer);
if (handlers != null) {
try {
chainLock.lock();
for (SAML2Handler handler : handlers) {
handler.handleRequestType(saml2HandlerRequest, saml2HandlerResponse);
willSendRequest = saml2HandlerResponse.getSendRequest();
}
} finally {
chainLock.unlock();
}
}
samlResponse = saml2HandlerResponse.getResultingDocument();
relayState = saml2HandlerResponse.getRelayState();
destination = saml2HandlerResponse.getDestination();
requestedPostProfile = saml2HandlerResponse.isPostBindingForResponse();
destinationQueryStringWithSignature = saml2HandlerResponse.getDestinationQueryStringWithSignature();
} catch (Exception e) {
String status = JBossSAMLURIConstants.STATUS_AUTHNFAILED.get();
if (e instanceof IssuerNotTrustedException || e.getCause() instanceof IssuerNotTrustedException) {
status = JBossSAMLURIConstants.STATUS_REQUEST_DENIED.get();
}
logger.samlIDPRequestProcessingError(e);
samlResponse = webRequestUtil.getErrorResponse(referer, status, getIdentityURL(),
this.idpConfiguration.isSupportsSignature());
isErrorResponse = true;
} finally {
try {
// if the destination is null, probably because some error occur during authentication, use the AuthnRequest
// AssertionConsumerServiceURL as the destination
if (destination == null && samlObject instanceof AuthnRequestType) {
AuthnRequestType authRequest = (AuthnRequestType) samlObject;
destination = authRequest.getAssertionConsumerServiceURL().toASCIIString();
}
// if destination is still empty redirect the user to the identity url. If the user is already authenticated he
// will be probably redirected to the idp hosted page.
if (destination == null) {
response.sendRedirect(getIdentityURL());
} else {
WebRequestUtilHolder holder = webRequestUtil.getHolder();
holder.setResponseDoc(samlResponse).setDestination(destination).setRelayState(relayState)
.setAreWeSendingRequest(willSendRequest).setPrivateKey(null).setSupportSignature(false)
.setErrorResponse(isErrorResponse).setServletResponse(response)
.setDestinationQueryStringWithSignature(destinationQueryStringWithSignature);
holder.setStrictPostBinding(this.idpConfiguration.isStrictPostBinding());
if (requestedPostProfile != null)
holder.setPostBindingRequested(requestedPostProfile);
else
holder.setPostBindingRequested(webRequestUtil.hasSAMLRequestInPostProfile());
if (this.idpConfiguration.isSupportsSignature()) {
holder.setPrivateKey(keyManager.getSigningKey()).setSupportSignature(true);
}
if (holder.isPostBinding())
recycle(response);
if (enableAudit) {
PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent(AuditLevel.INFO);
auditEvent.setType(PicketLinkAuditEventType.RESPONSE_TO_SP);
auditEvent.setDestination(destination);
auditEvent.setWhoIsAuditing(contextPath);
auditHelper.audit(auditEvent);
}
webRequestUtil.send(holder);
}
} catch (ParsingException e) {
logger.samlAssertionPasingFailed(e);
} catch (GeneralSecurityException e) {
logger.trace("Security Exception:", e);