use of com.sun.identity.saml2.profile.ServerFaultException in project OpenAM by OpenRock.
the class UtilProxyIDPRequestValidator method getIDPEntity.
/**
* The entity identifier for the IDP.
*
* @param idpMetaAlias Non null meta alias
* @param realm the realm for the entity identifier
* @return Non null String containing the entity identifier
* @throws ServerFaultException If unable to read the IDP Entity ID from the realm meta.
* @throws ClientFaultException If the client requested an invalid binding for this IDP.
*/
public String getIDPEntity(String idpMetaAlias, String realm) throws ServerFaultException, ClientFaultException {
String idpEntityID;
try {
idpEntityID = saml2MetaManager.getEntityByMetaAlias(idpMetaAlias);
if (StringUtils.isBlank(idpEntityID)) {
debug.error("Failed to locate IDP Entity ID\nRealm: {0}\nIDP Meta Alias: {1}", realm, idpMetaAlias);
LogUtil.error(Level.INFO, LogUtil.INVALID_IDP, new String[] { idpEntityID }, null);
throw new ClientFaultException("nullIDPEntityID");
}
boolean profileEnabled = SAML2Utils.isIDPProfileBindingSupported(realm, idpEntityID, SAML2Constants.SSO_SERVICE, reqBinding);
if (!profileEnabled) {
debug.error("SSO Binding {0} is not enabled for {0}", reqBinding, idpEntityID);
LogUtil.error(Level.INFO, LogUtil.BINDING_NOT_SUPPORTED, new String[] { idpEntityID, reqBinding }, null);
throw new ClientFaultException("unsupportedBinding");
}
} catch (SAML2MetaException sme) {
debug.error("Unable to get IDP Entity ID from meta: {0}", sme.getMessage());
LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, new String[] { idpMetaAlias }, null);
throw new ServerFaultException("nullIDPEntityID", sme.getMessage());
}
return idpEntityID;
}
use of com.sun.identity.saml2.profile.ServerFaultException in project OpenAM by OpenRock.
the class UtilProxySAMLAuthenticator method authenticate.
@Override
public void authenticate() throws FederatedSSOException, IOException {
final String classMethod = "UtilProxySAMLAuthenticator.authenticate: ";
SPSSODescriptorElement spSSODescriptor = null;
String preferredIDP;
// There is no reqID, this is the first time that we pass here.
String binding = SAML2Constants.HTTP_REDIRECT;
if (request.getMethod().equals("POST")) {
binding = SAML2Constants.HTTP_POST;
}
data.setAuthnRequest(getAuthnRequest(request, isFromECP, binding));
if (data.getAuthnRequest() == null) {
throw new ClientFaultException(data.getIdpAdapter(), INVALID_SAML_REQUEST);
}
data.getEventAuditor().setRequestId(data.getRequestID());
data.setSpEntityID(data.getAuthnRequest().getIssuer().getValue());
try {
logAccess(isFromECP ? LogUtil.RECEIVED_AUTHN_REQUEST_ECP : LogUtil.RECEIVED_AUTHN_REQUEST, Level.INFO, data.getSpEntityID(), data.getIdpMetaAlias(), data.getAuthnRequest().toXMLString());
} catch (SAML2Exception saml2ex) {
SAML2Utils.debug.error(classMethod, saml2ex);
throw new ClientFaultException(data.getIdpAdapter(), INVALID_SAML_REQUEST, saml2ex.getMessage());
}
if (!SAML2Utils.isSourceSiteValid(data.getAuthnRequest().getIssuer(), data.getRealm(), data.getIdpEntityID())) {
SAML2Utils.debug.warning("{} Issuer in Request is not valid.", classMethod);
throw new ClientFaultException(data.getIdpAdapter(), INVALID_SAML_REQUEST);
}
// verify the signature of the query string if applicable
IDPSSODescriptorElement idpSSODescriptor;
try {
idpSSODescriptor = IDPSSOUtil.metaManager.getIDPSSODescriptor(data.getRealm(), data.getIdpEntityID());
} catch (SAML2MetaException sme) {
SAML2Utils.debug.error(classMethod + "Unable to get IDP SSO Descriptor from meta.");
throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
}
try {
spSSODescriptor = IDPSSOUtil.metaManager.getSPSSODescriptor(data.getRealm(), data.getSpEntityID());
} catch (SAML2MetaException sme) {
SAML2Utils.debug.error(classMethod + "Unable to get SP SSO Descriptor from meta.");
SAML2Utils.debug.error(classMethod, sme);
}
if (isFromECP || idpSSODescriptor.isWantAuthnRequestsSigned() || (spSSODescriptor != null && spSSODescriptor.isAuthnRequestsSigned())) {
// need to verify the query string containing authnRequest
if (StringUtils.isBlank(data.getSpEntityID())) {
throw new ClientFaultException(data.getIdpAdapter(), INVALID_SAML_REQUEST);
}
if (spSSODescriptor == null) {
SAML2Utils.debug.error(classMethod + "Unable to get SP SSO Descriptor from meta.");
throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
}
Set<X509Certificate> certificates = KeyUtil.getVerificationCerts(spSSODescriptor, data.getSpEntityID(), SAML2Constants.SP_ROLE);
try {
boolean isSignatureOK;
if (isFromECP) {
isSignatureOK = data.getAuthnRequest().isSignatureValid(certificates);
} else {
if ("POST".equals(request.getMethod())) {
isSignatureOK = data.getAuthnRequest().isSignatureValid(certificates);
} else {
isSignatureOK = QuerySignatureUtil.verify(request.getQueryString(), certificates);
}
}
if (!isSignatureOK) {
SAML2Utils.debug.error(classMethod + "authn request verification failed.");
throw new ClientFaultException(data.getIdpAdapter(), "invalidSignInRequest");
}
// In ECP profile, sp doesn't know idp.
if (!isFromECP) {
// verify Destination
List ssoServiceList = idpSSODescriptor.getSingleSignOnService();
String ssoURL = SPSSOFederate.getSSOURL(ssoServiceList, binding);
if (!SAML2Utils.verifyDestination(data.getAuthnRequest().getDestination(), ssoURL)) {
SAML2Utils.debug.error(classMethod + "authn request destination verification failed.");
throw new ClientFaultException(data.getIdpAdapter(), "invalidDestination");
}
}
} catch (SAML2Exception se) {
SAML2Utils.debug.error(classMethod + "authn request verification failed.", se);
throw new ClientFaultException(data.getIdpAdapter(), "invalidSignInRequest");
}
SAML2Utils.debug.message("{} authn request signature verification is successful.", classMethod);
}
SAML2Utils.debug.message("{} request id= {}", classMethod, data.getRequestID());
if (data.getRequestID() == null) {
SAML2Utils.debug.error(classMethod + "Request id is null");
throw new ClientFaultException(data.getIdpAdapter(), "InvalidSAMLRequestID");
}
if (isFromECP) {
try {
IDPECPSessionMapper idpECPSessonMapper = IDPSSOUtil.getIDPECPSessionMapper(data.getRealm(), data.getIdpEntityID());
data.setSession(idpECPSessonMapper.getSession(request, response));
} catch (SAML2Exception se) {
SAML2Utils.debug.message("Unable to retrieve user session.", classMethod);
}
} else {
// get the user sso session from the request
try {
data.setSession(SessionManager.getProvider().getSession(request));
} catch (SessionException se) {
SAML2Utils.debug.message("{} Unable to retrieve user session.", classMethod);
}
}
if (null != data.getSession()) {
data.getEventAuditor().setAuthTokenId(data.getSession());
}
// will not trigger this adapter call
if (preSingleSignOn(request, response, data)) {
return;
}
// End of adapter invocation
IDPAuthnContextMapper idpAuthnContextMapper = null;
try {
idpAuthnContextMapper = IDPSSOUtil.getIDPAuthnContextMapper(data.getRealm(), data.getIdpEntityID());
} catch (SAML2Exception sme) {
SAML2Utils.debug.error(classMethod, sme);
}
if (idpAuthnContextMapper == null) {
SAML2Utils.debug.error(classMethod + "Unable to get IDPAuthnContextMapper from meta.");
throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
}
IDPAuthnContextInfo idpAuthnContextInfo = null;
try {
idpAuthnContextInfo = idpAuthnContextMapper.getIDPAuthnContextInfo(data.getAuthnRequest(), data.getIdpEntityID(), data.getRealm());
} catch (SAML2Exception sme) {
SAML2Utils.debug.error(classMethod, sme);
}
if (idpAuthnContextInfo == null) {
SAML2Utils.debug.message("{} Unable to find valid AuthnContext. Sending error Response.", classMethod);
try {
Response res = SAML2Utils.getErrorResponse(data.getAuthnRequest(), SAML2Constants.REQUESTER, SAML2Constants.NO_AUTHN_CONTEXT, null, data.getIdpEntityID());
StringBuffer returnedBinding = new StringBuffer();
String acsURL = IDPSSOUtil.getACSurl(data.getSpEntityID(), data.getRealm(), data.getAuthnRequest(), request, returnedBinding);
String acsBinding = returnedBinding.toString();
IDPSSOUtil.sendResponse(request, response, out, acsBinding, data.getSpEntityID(), data.getIdpEntityID(), data.getIdpMetaAlias(), data.getRealm(), data.getRelayState(), acsURL, res, data.getSession());
} catch (SAML2Exception sme) {
SAML2Utils.debug.error(classMethod, sme);
throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
}
return;
}
// get the relay state query parameter from the request
data.setRelayState(request.getParameter(SAML2Constants.RELAY_STATE));
data.setMatchingAuthnContext(idpAuthnContextInfo.getAuthnContext());
if (data.getSession() == null) {
// the user has not logged in yet, redirect to auth
redirectToAuth(spSSODescriptor, binding, idpAuthnContextInfo, data);
} else {
SAML2Utils.debug.message("{} There is an existing session", classMethod);
// Let's verify that the realm is the same for the user and the IdP
boolean isValidSessionInRealm = IDPSSOUtil.isValidSessionInRealm(data.getRealm(), data.getSession());
String sessionIndex = IDPSSOUtil.getSessionIndex(data.getSession());
boolean sessionUpgrade = false;
if (isValidSessionInRealm) {
sessionUpgrade = isSessionUpgrade(idpAuthnContextInfo, data.getSession());
SAML2Utils.debug.message("{} IDP Session Upgrade is : {}", classMethod, sessionUpgrade);
}
// Holder for any exception encountered while redirecting for authentication:
FederatedSSOException redirectException = null;
if (sessionUpgrade || !isValidSessionInRealm || ((Boolean.TRUE.equals(data.getAuthnRequest().isForceAuthn())) && (!Boolean.TRUE.equals(data.getAuthnRequest().isPassive())))) {
// sessionIndex
if (sessionIndex != null && sessionIndex.length() != 0) {
// Save the original IDP Session
IDPSession oldIDPSession = IDPCache.idpSessionsByIndices.get(sessionIndex);
if (oldIDPSession != null) {
IDPCache.oldIDPSessionCache.put(data.getRequestID(), oldIDPSession);
} else {
SAML2Utils.debug.error(classMethod + "The old SAML2 session was not found in the idp session " + "by indices cache");
}
}
// Save the new requestId and AuthnRequest
IDPCache.authnRequestCache.put(data.getRequestID(), new CacheObject(data.getAuthnRequest()));
// Save the new requestId and AuthnContext
IDPCache.idpAuthnContextCache.put(data.getRequestID(), new CacheObject(data.getMatchingAuthnContext()));
// save if the request was an Session Upgrade case.
IDPCache.isSessionUpgradeCache.add(data.getRequestID());
// authenticates
if (StringUtils.isNotBlank(data.getRelayState())) {
IDPCache.relayStateCache.put(data.getRequestID(), data.getRelayState());
}
// Session upgrade could be requested by asking a greater AuthnContext
if (isValidSessionInRealm) {
try {
boolean isProxy = IDPProxyUtil.isIDPProxyEnabled(data.getAuthnRequest(), data.getRealm());
if (isProxy) {
preferredIDP = IDPProxyUtil.getPreferredIDP(data.getAuthnRequest(), data.getIdpEntityID(), data.getRealm(), request, response);
if (preferredIDP != null) {
if ((SPCache.reqParamHash != null) && (!(SPCache.reqParamHash.containsKey(preferredIDP)))) {
// IDP Proxy with configured proxy list
SAML2Utils.debug.message("{} IDP to be proxied {}", classMethod, preferredIDP);
IDPProxyUtil.sendProxyAuthnRequest(data.getAuthnRequest(), preferredIDP, spSSODescriptor, data.getIdpEntityID(), request, response, data.getRealm(), data.getRelayState(), binding);
return;
} else {
// IDP proxy with introduction cookie
Map paramsMap = (Map) SPCache.reqParamHash.get(preferredIDP);
paramsMap.put("authnReq", data.getAuthnRequest());
paramsMap.put("spSSODescriptor", spSSODescriptor);
paramsMap.put("idpEntityID", data.getIdpEntityID());
paramsMap.put("realm", data.getRealm());
paramsMap.put("relayState", data.getRelayState());
paramsMap.put("binding", binding);
SPCache.reqParamHash.put(preferredIDP, paramsMap);
return;
}
}
}
//else continue for the local authentication.
} catch (SAML2Exception re) {
SAML2Utils.debug.message("{} Redirecting for the proxy handling error: {}", classMethod, re.getMessage());
redirectException = new ServerFaultException(data.getIdpAdapter(), "UnableToRedirectToPreferredIDP", re.getMessage());
}
// End of IDP Proxy: Initiate proxying when session upgrade is requested
}
// Invoke the IDP Adapter before redirecting to authn
if (preAuthenticationAdapter(request, response, data)) {
return;
}
//we don't have a session
try {
//and they want to authenticate
if (!Boolean.TRUE.equals(data.getAuthnRequest().isPassive())) {
redirectAuthentication(request, response, idpAuthnContextInfo, data, true);
return;
} else {
try {
//and they want to get into the system with passive auth - response no passive
IDPSSOUtil.sendNoPassiveResponse(request, response, out, data.getIdpMetaAlias(), data.getIdpEntityID(), data.getRealm(), data.getAuthnRequest(), data.getRelayState(), data.getSpEntityID());
} catch (SAML2Exception sme) {
SAML2Utils.debug.error(classMethod, sme);
redirectException = new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
}
}
} catch (IOException | SAML2Exception e) {
SAML2Utils.debug.error(classMethod + "Unable to redirect to authentication.", e);
sessionUpgrade = false;
cleanUpCache(data.getRequestID());
redirectException = new ServerFaultException(data.getIdpAdapter(), "UnableToRedirectToAuth", e.getMessage());
}
}
// generate assertion response
if (!sessionUpgrade && isValidSessionInRealm) {
generateAssertionResponse(data);
}
if (redirectException != null) {
throw redirectException;
}
}
}
use of com.sun.identity.saml2.profile.ServerFaultException in project OpenAM by OpenRock.
the class UtilProxySAMLAuthenticator method redirectToAuth.
private void redirectToAuth(SPSSODescriptorElement spSSODescriptor, String binding, IDPAuthnContextInfo idpAuthnContextInfo, IDPSSOFederateRequest data) throws IOException, ServerFaultException {
String classMethod = "IDPSSOFederate.redirectToAuth";
String preferredIDP;
// retrieved later when the user successfully authenticates
synchronized (IDPCache.authnRequestCache) {
IDPCache.authnRequestCache.put(data.getRequestID(), new CacheObject(data.getAuthnRequest()));
}
// retrieved later when the user successfully authenticates
synchronized (IDPCache.idpAuthnContextCache) {
IDPCache.idpAuthnContextCache.put(data.getRequestID(), new CacheObject(data.getMatchingAuthnContext()));
}
// retrieved later when the user successfully authenticates
if (StringUtils.isNotBlank(data.getRelayState())) {
IDPCache.relayStateCache.put(data.getRequestID(), data.getRelayState());
}
//IDP Proxy: Initiate proxying
try {
boolean isProxy = IDPProxyUtil.isIDPProxyEnabled(data.getAuthnRequest(), data.getRealm());
if (isProxy) {
preferredIDP = IDPProxyUtil.getPreferredIDP(data.getAuthnRequest(), data.getIdpEntityID(), data.getRealm(), request, response);
if (preferredIDP != null) {
if ((SPCache.reqParamHash != null) && (!(SPCache.reqParamHash.containsKey(preferredIDP)))) {
// IDP Proxy with configured proxy list
SAML2Utils.debug.message("{} IDP to be proxied {} ", classMethod, preferredIDP);
IDPProxyUtil.sendProxyAuthnRequest(data.getAuthnRequest(), preferredIDP, spSSODescriptor, data.getIdpEntityID(), request, response, data.getRealm(), data.getRelayState(), binding);
return;
} else {
// IDP proxy with introduction cookie
Map paramsMap = (Map) SPCache.reqParamHash.get(preferredIDP);
paramsMap.put("authnReq", data.getAuthnRequest());
paramsMap.put("spSSODescriptor", spSSODescriptor);
paramsMap.put("idpEntityID", data.getIdpEntityID());
paramsMap.put("realm", data.getRealm());
paramsMap.put("relayState", data.getRelayState());
paramsMap.put("binding", binding);
SPCache.reqParamHash.put(preferredIDP, paramsMap);
return;
}
}
}
//else continue for the local authentication.
} catch (SAML2Exception re) {
SAML2Utils.debug.message("{} Redirecting for the proxy handling error: {}", classMethod, re.getMessage());
throw new ServerFaultException(data.getIdpAdapter(), "UnableToRedirectToPreferredIDP", re.getMessage());
}
// preAuthentication adapter hook
if (preAuthenticationAdapter(request, response, data)) {
return;
}
// redirect to the authentication service
try {
if (!Boolean.TRUE.equals(data.getAuthnRequest().isPassive())) {
redirectAuthentication(request, response, idpAuthnContextInfo, data, false);
} else {
try {
IDPSSOUtil.sendNoPassiveResponse(request, response, out, data.getIdpMetaAlias(), data.getIdpEntityID(), data.getRealm(), data.getAuthnRequest(), data.getRelayState(), data.getSpEntityID());
} catch (SAML2Exception sme) {
SAML2Utils.debug.error(classMethod, sme);
throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
}
}
} catch (IOException | SAML2Exception e) {
SAML2Utils.debug.error(classMethod + "Unable to redirect to authentication.", e);
throw new ServerFaultException(data.getIdpAdapter(), "UnableToRedirectToAuth", e.getMessage());
}
}
use of com.sun.identity.saml2.profile.ServerFaultException in project OpenAM by OpenRock.
the class UtilProxySAMLAuthenticatorLookup method authNotAvailable.
private void authNotAvailable() throws ServerFaultException {
final String classMethod = "UtilProxySAMLAuthenticatorLookup.authNotavailable";
//handle the case when the authn request is no longer available in the local cache. This could
//happen for multiple reasons:
// - the SAML response has been already sent back for this request (e.g. browser back button)
// - the second visit reached a different OpenAM server, than the first and SAML SFO is disabled
// - the cache interval has passed
SAML2Utils.debug.error(classMethod + "Unable to get AuthnRequest from cache, sending error response");
try {
SAML2Utils.debug.message("Invoking IDP adapter preSendFailureResponse hook");
try {
data.getIdpAdapter().preSendFailureResponse(request, response, SAML2Constants.SERVER_FAULT, "UnableToGetAuthnReq");
} catch (SAML2Exception se2) {
SAML2Utils.debug.error("Error invoking the IDP Adapter", se2);
}
Response res = SAML2Utils.getErrorResponse(null, SAML2Constants.RESPONDER, null, null, data.getIdpEntityID());
res.setInResponseTo(data.getRequestID());
StringBuffer returnedBinding = new StringBuffer();
String spEntityID = request.getParameter(SP_ENTITY_ID);
String acsURL = request.getParameter(ACS_URL);
String binding = request.getParameter(BINDING);
Integer index;
try {
index = Integer.valueOf(request.getParameter(INDEX));
} catch (NumberFormatException nfe) {
index = null;
}
acsURL = IDPSSOUtil.getACSurl(spEntityID, data.getRealm(), acsURL, binding, index, request, returnedBinding);
String acsBinding = returnedBinding.toString();
IDPSSOUtil.sendResponse(request, response, out, acsBinding, spEntityID, data.getIdpEntityID(), data.getIdpMetaAlias(), data.getRealm(), data.getRelayState(), acsURL, res, data.getSession());
} catch (SAML2Exception sme) {
SAML2Utils.debug.error(classMethod + "an error occured while sending error response", sme);
throw new ServerFaultException(data.getIdpAdapter(), "UnableToGetAuthnReq");
}
}
use of com.sun.identity.saml2.profile.ServerFaultException in project OpenAM by OpenRock.
the class UtilProxySAMLAuthenticatorLookup method isSessionValid.
private boolean isSessionValid(SessionProvider sessionProvider) throws ServerFaultException, ClientFaultException, SessionException {
final String classMethod = "UtilProxySAMLAuthenticatorLookup.validteSesison";
// Let's verify if the session belongs to the proper realm
boolean isValidSessionInRealm = data.getSession() != null && IDPSSOUtil.isValidSessionInRealm(data.getRealm(), data.getSession());
// If there is a session then it must belong to the proper realm
if (!isValidSessionInRealm) {
if (data.getAuthnRequest() != null && Boolean.TRUE.equals(data.getAuthnRequest().isPassive())) {
// Send an appropriate response to the passive request
data.setSpEntityID(data.getAuthnRequest().getIssuer().getValue());
try {
IDPSSOUtil.sendNoPassiveResponse(request, response, out, data.getIdpMetaAlias(), data.getIdpEntityID(), data.getRealm(), data.getAuthnRequest(), data.getRelayState(), data.getSpEntityID());
return false;
} catch (SAML2Exception sme) {
SAML2Utils.debug.error(classMethod, sme);
throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
}
} else {
// No attempt to authenticate now, since it is assumed that that has already been tried
String ipAddress = request.getRemoteAddr();
String authnReqString = "";
try {
authnReqString = data.getAuthnRequest() == null ? "" : data.getAuthnRequest().toXMLString();
} catch (SAML2Exception ex) {
SAML2Utils.debug.error(classMethod + "Could not obtain the AuthnReq to be logged");
}
if (data.getSession() == null) {
SAML2Utils.debug.error(classMethod + "The IdP has not been able to create a session");
logError(Level.INFO, LogUtil.SSO_NOT_FOUND, null, null, "null", data.getRealm(), data.getIdpEntityID(), ipAddress, authnReqString);
} else {
SAML2Utils.debug.error(classMethod + "The realm of the session does not correspond to that " + "of the IdP");
logError(Level.INFO, LogUtil.INVALID_REALM_FOR_SESSION, data.getSession(), null, sessionProvider.getProperty(data.getSession(), SAML2Constants.ORGANIZATION)[0], data.getRealm(), data.getIdpEntityID(), ipAddress, authnReqString);
}
throw new ClientFaultException(data.getIdpAdapter(), SSO_OR_FEDERATION_ERROR);
}
}
return true;
}
Aggregations