use of com.sun.identity.multiprotocol.SingleLogoutManager in project OpenAM by OpenRock.
the class WSFederationUtils method processMultiProtocolLogout.
/**
* Processes Single Logout cross multiple federation protocols
* @param request HttpServletRequest object.
* @param response HttpServletResponse object
*/
public static void processMultiProtocolLogout(HttpServletRequest request, HttpServletResponse response, Object userSession) {
debug.message("WSFederationUtils.processMPSingleLogout");
try {
String wreply = (String) request.getAttribute(WSFederationConstants.LOGOUT_WREPLY);
String realm = (String) request.getAttribute(WSFederationConstants.REALM_PARAM);
String idpEntityId = (String) request.getAttribute(WSFederationConstants.ENTITYID_PARAM);
Set sessSet = new HashSet();
sessSet.add(userSession);
String sessUser = SessionManager.getProvider().getPrincipalName(userSession);
// assume WS-Federation logout always succeed as there is not
// logout status from the specification
SingleLogoutManager manager = SingleLogoutManager.getInstance();
// TODO : find out spEntityID/logout request if any
int status = manager.doIDPSingleLogout(sessSet, sessUser, request, response, false, true, SingleLogoutManager.WS_FED, realm, idpEntityId, null, wreply, null, null, SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS);
if (status != SingleLogoutManager.LOGOUT_REDIRECTED_STATUS) {
response.sendRedirect(wreply);
}
} catch (SessionException ex) {
// ignore;
debug.message("WSFederationUtils.processMultiProtocolLogout", ex);
} catch (IOException ex) {
// ignore;
debug.message("WSFederationUtils.processMultiProtocolLogout", ex);
} catch (Exception ex) {
// ignore;
debug.message("WSFederationUtils.processMultiProtocolLogout", ex);
}
}
use of com.sun.identity.multiprotocol.SingleLogoutManager in project OpenAM by OpenRock.
the class IDPSingleLogout method sendLastResponse.
private static boolean sendLastResponse(IDPSession idpSession, LogoutResponse logoutRes, HttpServletRequest request, HttpServletResponse response, String idpSessionIndex, Object session, String realm, String idpEntityID, String relayState) throws SAML2Exception, SessionException, SAML2MetaException {
String binding;
//resetting the binding to the original value so the response is sent back with the correct binding
binding = idpSession.getOriginatingLogoutRequestBinding();
String originatingRequestID = idpSession.getOriginatingLogoutRequestID();
String originatingLogoutSPEntityID = idpSession.getOriginatingLogoutSPEntityID();
if (originatingRequestID == null) {
// this is IDP initiated SLO
if (idpSession.getLogoutAll()) {
String userID = sessionProvider.getPrincipalName(idpSession.getSession());
destroyAllTokenForUser(userID, request, response);
} else {
IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
if (agent != null && agent.isRunning() && saml2Svc != null) {
saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
}
try {
if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
}
} catch (SAML2TokenRepositoryException se) {
debug.error("IDPSingleLogout.sendLastResponse: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
}
IDPCache.authnContextCache.remove(idpSessionIndex);
if (!MultiProtocolUtils.isMultipleProtocolSession(idpSession.getSession(), SingleLogoutManager.SAML2)) {
sessionProvider.invalidateSession(idpSession.getSession(), request, response);
} else {
MultiProtocolUtils.removeFederationProtocol(idpSession.getSession(), SingleLogoutManager.SAML2);
// call Multi-Federation protocol SingleLogoutManager
SingleLogoutManager sloManager = SingleLogoutManager.getInstance();
Set<Object> set = new HashSet<Object>(1);
set.add(session);
SessionProvider provider = SessionManager.getProvider();
String uid = provider.getPrincipalName(session);
debug.message("IDPSingleLogout.sendLastResponse: MP/Http");
int retStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
try {
retStatus = sloManager.doIDPSingleLogout(set, uid, request, response, false, true, SingleLogoutManager.SAML2, realm, idpEntityID, originatingLogoutSPEntityID, relayState, null, null, getLogoutStatus(logoutRes));
} catch (SAML2Exception ex) {
throw ex;
} catch (Exception ex) {
debug.error("IDPSIngleLogout.sendLastResponse: MP/IDP initiated HTTP", ex);
throw new SAML2Exception(ex.getMessage());
}
if (retStatus == SingleLogoutManager.LOGOUT_REDIRECTED_STATUS) {
return true;
}
}
}
debug.message("IDP initiated SLO Success");
return false;
}
List<SingleLogoutServiceElement> slosList = getSPSLOServiceEndpoints(realm, originatingLogoutSPEntityID);
String location = LogoutUtil.getSLOResponseServiceLocation(slosList, binding);
if (location == null || location.isEmpty()) {
location = LogoutUtil.getSLOServiceLocation(slosList, binding);
if (location == null || location.length() == 0) {
debug.error("Unable to find the IDP's single logout response service with the HTTP-Redirect binding");
throw new SAML2Exception(SAML2Utils.bundle.getString("sloResponseServiceLocationNotfound"));
} else {
if (debug.messageEnabled()) {
debug.message("SP's single logout response service location = " + location);
}
}
} else {
if (debug.messageEnabled()) {
debug.message("IDP's single logout response service location = " + location);
}
}
Status status = destroyTokenAndGenerateStatus(idpSessionIndex, idpSession.getSession(), request, response, true);
//here we are providing null for remote entity, because it's an unused variable in the method...
logoutRes = LogoutUtil.generateResponse(status, originatingRequestID, SAML2Utils.createIssuer(idpEntityID), realm, SAML2Constants.IDP_ROLE, null);
if (logoutRes != null) {
logoutRes.setDestination(XMLUtils.escapeSpecialCharacters(location));
IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
if (agent != null && agent.isRunning() && saml2Svc != null) {
saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
}
try {
if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
}
} catch (SAML2TokenRepositoryException se) {
debug.error("IDPSingleLogout.sendLastResponse: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
}
IDPCache.authnContextCache.remove(idpSessionIndex);
// call multi-federation protocol processing
// this is the SP initiated HTTP binding case
boolean isMultiProtocolSession = false;
int retStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
try {
SessionProvider provider = SessionManager.getProvider();
session = idpSession.getSession();
if (session != null && provider.isValid(session) && MultiProtocolUtils.isMultipleProtocolSession(session, SingleLogoutManager.SAML2)) {
isMultiProtocolSession = true;
// call Multi-Federation protocol SingleLogoutManager
SingleLogoutManager sloManager = SingleLogoutManager.getInstance();
Set set = new HashSet();
set.add(session);
String uid = provider.getPrincipalName(session);
debug.message("IDPSingleLogout.sendLastResponse: MP/Http");
retStatus = sloManager.doIDPSingleLogout(set, uid, request, response, false, true, SingleLogoutManager.SAML2, realm, idpEntityID, originatingLogoutSPEntityID, relayState, null, logoutRes.toXMLString(), getLogoutStatus(logoutRes));
}
} catch (SessionException e) {
// ignore as session might not be valid
debug.message("IDPSingleLogout.sendLastResponse: session", e);
} catch (Exception e) {
debug.message("IDPSingleLogout.sendLastResponse: MP2", e);
retStatus = SingleLogoutManager.LOGOUT_FAILED_STATUS;
}
if (!isMultiProtocolSession || (retStatus != SingleLogoutManager.LOGOUT_REDIRECTED_STATUS)) {
logoutRes = updateLogoutResponse(logoutRes, retStatus);
LogoutUtil.sendSLOResponse(response, request, logoutRes, location, relayState, realm, idpEntityID, SAML2Constants.IDP_ROLE, originatingLogoutSPEntityID, binding);
return true;
} else {
return false;
}
}
IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
if (agent != null && agent.isRunning() && saml2Svc != null) {
saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
}
try {
if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
}
} catch (SAML2TokenRepositoryException se) {
debug.error("IDPSingleLogout.sendLastResponse: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
}
IDPCache.authnContextCache.remove(idpSessionIndex);
return false;
}
use of com.sun.identity.multiprotocol.SingleLogoutManager in project OpenAM by OpenRock.
the class IDPSingleLogout method processLogoutRequest.
/**
* Gets and processes the Single <code>LogoutRequest</code> from SP.
*
* @param request the HttpServletRequest.
* @param response the HttpServletResponse.
* @param out the print writer for writing out presentation
* @param samlRequest <code>LogoutRequest</code> in the
* XML string format.
* @param relayState the target URL on successful
* <code>LogoutRequest</code>.
* @throws SAML2Exception if error processing
* <code>LogoutRequest</code>.
* @throws SessionException if error processing
* <code>LogoutRequest</code>.
*/
public static void processLogoutRequest(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String samlRequest, String relayState) throws SAML2Exception, SessionException {
String classMethod = "IDPSingleLogout.processLogoutRequest : ";
if (debug.messageEnabled()) {
debug.message(classMethod + "IDPSingleLogout:processLogoutRequest");
debug.message(classMethod + "samlRequest : " + samlRequest);
debug.message(classMethod + "relayState : " + relayState);
}
String rmethod = request.getMethod();
String binding = SAML2Constants.HTTP_REDIRECT;
if (rmethod.equals("POST")) {
binding = SAML2Constants.HTTP_POST;
}
String metaAlias = SAML2MetaUtils.getMetaAliasByUri(request.getRequestURI());
String realm = SAML2Utils.getRealm(SAML2MetaUtils.getRealmByMetaAlias(metaAlias));
String idpEntityID = sm.getEntityByMetaAlias(metaAlias);
if (!SAML2Utils.isIDPProfileBindingSupported(realm, idpEntityID, SAML2Constants.SLO_SERVICE, binding)) {
debug.error(classMethod + "SLO service binding " + binding + " is not supported for " + idpEntityID);
throw new SAML2Exception(SAML2Utils.bundle.getString("unsupportedBinding"));
}
LogoutRequest logoutReq = null;
if (rmethod.equals("POST")) {
logoutReq = LogoutUtil.getLogoutRequestFromPost(samlRequest, response);
} else if (rmethod.equals("GET")) {
String decodedStr = SAML2Utils.decodeFromRedirect(samlRequest);
if (decodedStr == null) {
throw new SAML2Exception(SAML2Utils.bundle.getString("nullDecodedStrFromSamlRequest"));
}
logoutReq = ProtocolFactory.getInstance().createLogoutRequest(decodedStr);
}
if (logoutReq == null) {
if (debug.messageEnabled()) {
debug.message("IDPSingleLogout:processLogoutRequest: logoutReq " + "is null");
}
return;
}
String spEntityID = logoutReq.getIssuer().getValue();
boolean needToVerify = SAML2Utils.getWantLogoutRequestSigned(realm, idpEntityID, SAML2Constants.IDP_ROLE);
if (debug.messageEnabled()) {
debug.message(classMethod + "metaAlias : " + metaAlias);
debug.message(classMethod + "realm : " + realm);
debug.message(classMethod + "idpEntityID : " + idpEntityID);
debug.message(classMethod + "spEntityID : " + spEntityID);
}
if (needToVerify) {
boolean valid = false;
if (binding.equals(SAML2Constants.HTTP_REDIRECT)) {
String queryString = request.getQueryString();
valid = SAML2Utils.verifyQueryString(queryString, realm, SAML2Constants.IDP_ROLE, spEntityID);
} else {
valid = LogoutUtil.verifySLORequest(logoutReq, realm, spEntityID, idpEntityID, SAML2Constants.IDP_ROLE);
}
if (!valid) {
debug.error("Invalid signature in SLO Request.");
throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSignInRequest"));
}
IDPSSODescriptorElement idpsso = sm.getIDPSSODescriptor(realm, idpEntityID);
String loc = null;
if (idpsso != null) {
List sloList = idpsso.getSingleLogoutService();
if ((sloList != null) && (!sloList.isEmpty())) {
loc = LogoutUtil.getSLOResponseServiceLocation(sloList, binding);
if ((loc == null) || (loc.length() == 0)) {
loc = LogoutUtil.getSLOServiceLocation(sloList, binding);
}
}
}
if (!SAML2Utils.verifyDestination(logoutReq.getDestination(), loc)) {
throw new SAML2Exception(SAML2Utils.bundle.getString("invalidDestination"));
}
}
// Get the local session, if it does not exist send a succesful
// Logout Response with a status message of "Already Logout"
Object session = null;
try {
session = sessionProvider.getSession(request);
} catch (SessionException ssoe) {
sendAlreadyLogedOutResp(response, request, logoutReq, relayState, realm, idpEntityID, spEntityID, binding);
return;
}
// then send the request to the original server
if (session != null && !SAML2FailoverUtils.isSAML2FailoverEnabled() && isMisroutedRequest(request, response, out, session)) {
return;
} else {
if (debug.messageEnabled()) {
debug.message(classMethod + "SAML2 Failover will be attempted. Be sure SFO is " + "properly configured or the attempt will fail");
}
}
LogoutResponse logoutRes = processLogoutRequest(logoutReq, request, response, binding, relayState, idpEntityID, realm, true);
if (logoutRes == null) {
// through HTTP_Redirect, nothing to do here
return;
}
// this is the case where there is no more SP session
// participant
SingleLogoutServiceElement endpoint = getLogoutResponseEndpoint(realm, spEntityID, binding);
binding = endpoint.getBinding();
String location = getResponseLocation(endpoint);
logoutRes.setDestination(XMLUtils.escapeSpecialCharacters(location));
// call multi-federation protocol processing
// this is SP initiated HTTP based single logout
boolean isMultiProtocolSession = false;
int retStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
try {
if ((session != null) && (sessionProvider.isValid(session)) && MultiProtocolUtils.isMultipleProtocolSession(session, SingleLogoutManager.SAML2)) {
isMultiProtocolSession = true;
// call Multi-Federation protocol SingleLogoutManager
SingleLogoutManager sloManager = SingleLogoutManager.getInstance();
Set set = new HashSet();
set.add(session);
String uid = sessionProvider.getPrincipalName(session);
debug.message("IDPSingleLogout.processLogReq: MP/SPinit/Http");
retStatus = sloManager.doIDPSingleLogout(set, uid, request, response, false, false, SingleLogoutManager.SAML2, realm, idpEntityID, spEntityID, relayState, logoutReq.toString(), logoutRes.toXMLString(), getLogoutStatus(logoutRes));
}
} catch (SessionException e) {
// ignore as session might not be valid
debug.message("IDPSingleLogout.processLogoutRequest: session", e);
} catch (Exception e) {
debug.message("IDPSingleLogout.processLogoutRequest: MP2", e);
retStatus = SingleLogoutManager.LOGOUT_FAILED_STATUS;
}
if (!isMultiProtocolSession || (retStatus != SingleLogoutManager.LOGOUT_REDIRECTED_STATUS)) {
logoutRes = updateLogoutResponse(logoutRes, retStatus);
List partners = IDPProxyUtil.getSessionPartners(request);
if (partners != null && !partners.isEmpty()) {
IDPProxyUtil.sendProxyLogoutRequest(request, response, out, logoutReq, partners, binding, relayState);
} else {
LogoutUtil.sendSLOResponse(response, request, logoutRes, location, relayState, realm, idpEntityID, SAML2Constants.IDP_ROLE, spEntityID, binding);
}
}
}
Aggregations