use of com.sun.identity.saml2.protocol.LogoutResponse in project OpenAM by OpenRock.
the class IDPSingleLogoutServiceSOAP method onMessage.
/**
* Process the incoming SOAP message containing the LogoutRequest and
* generates outgoing SOAP message containing the LogoutResponse on IDP
* side.
* @param message incoming SOAP message.
* @param request HTTP servlet request.
* @param response HTTP servlet response.
* @param idpEntityID Entity ID of the hosted IDP.
* @param realm realm of this hosted IDP.
* @return SOAP message containing the outgoing LogoutResponse.
*/
public SOAPMessage onMessage(SOAPMessage message, HttpServletRequest request, HttpServletResponse response, String idpEntityID, String realm) {
SAML2Utils.debug.message("IDPSingleLogoutServiceSOAP.onMessage: init");
// get LogoutRequest element from SOAP message
LogoutRequest logoutReq = null;
try {
Element reqElem = SOAPCommunicator.getInstance().getSamlpElement(message, "LogoutRequest");
logoutReq = ProtocolFactory.getInstance().createLogoutRequest(reqElem);
// delay the signature until this server finds the session
} catch (SAML2Exception se) {
SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " + "unable to get LogoutRequest from message", se);
return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "errorLogoutRequest", se.getMessage());
}
if (logoutReq == null) {
SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " + "LogoutRequest is null");
return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "nullLogoutRequest", null);
}
LogoutResponse loRes = null;
try {
// process LogoutRequestElement
loRes = IDPSingleLogout.processLogoutRequest(logoutReq, request, response, SAML2Constants.SOAP, null, idpEntityID, realm, false);
LogoutUtil.signSLOResponse(loRes, realm, idpEntityID, SAML2Constants.IDP_ROLE, logoutReq.getIssuer().getValue());
} catch (SAML2Exception e) {
SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage;", e);
return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT, "errorLogoutResponse", e.getMessage());
}
if (loRes == null) {
SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " + "LogoutResponse is null");
return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT, "errorLogoutResponse", null);
}
SOAPMessage msg = null;
try {
msg = SOAPCommunicator.getInstance().createSOAPMessage(loRes.toXMLString(true, true), false);
} catch (SAML2Exception se) {
SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " + "Unable to create SOAP message:", se);
return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT, "errorLogoutResponseSOAP", se.getMessage());
} catch (SOAPException ex) {
SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " + "Unable to create SOAP message:", ex);
return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT, "errorLogoutResponseSOAP", ex.getMessage());
}
return msg;
}
use of com.sun.identity.saml2.protocol.LogoutResponse in project OpenAM by OpenRock.
the class SingleLogoutManager method sendLogoutResponse.
/**
* Sends logout response, this is for the case of HTTP binding
* There are two cases here:
* 1. IDP initiated HTTP Logout, just redirect user browser to original
* relaystate.
* 2. SP initiated HTTP logout, need to send LogoutResponse back to SP.
*/
void sendLogoutResponse(HttpServletRequest request, HttpServletResponse response, String relayState) throws IOException {
if (debug.messageEnabled()) {
debug.message("SingleLogoutManager.sendLogoutResponse: relaystate=" + relayState);
}
String logoutResponseXML = (String) sloResponseXMLMap.get(relayState);
if (logoutResponseXML == null) {
// first case, just redirect to original relayState
String origRelayState = (String) relayStateMap.get(relayState);
int logoutStatus = ((Integer) currentStatusMap.get(relayState)).intValue();
String statusString = MultiProtocolUtils.getLogoutStatus(logoutStatus);
if ((origRelayState == null) || (origRelayState.length() == 0)) {
// TODO : get default single logout URL for each protocol
response.getWriter().print("Logout DONE. Status = " + statusString);
} else {
// include logout status
if (origRelayState.indexOf("?") == -1) {
response.sendRedirect(origRelayState + "?" + SingleLogoutManager.STATUS_PARAM + "=" + statusString);
} else {
response.sendRedirect(origRelayState + "&" + SingleLogoutManager.STATUS_PARAM + "=" + statusString);
}
}
} else {
String protocol = (String) origProtocolMap.get(relayState);
String spEntityID = (String) spEntityIDMap.get(relayState);
String origRelayState = (String) relayStateMap.get(relayState);
String realm = (String) realmMap.get(relayState);
String idpEntityID = (String) idpEntityIDMap.get(relayState);
int currentStatus = ((Integer) currentStatusMap.get(relayState)).intValue();
if (protocol.equals(SingleLogoutManager.SAML2)) {
try {
LogoutResponse logResp = ProtocolFactory.getInstance().createLogoutResponse(logoutResponseXML);
String location = logResp.getDestination();
String statusVal = logResp.getStatus().getStatusCode().getValue();
String newVal = getNewStatusCode(currentStatus, statusVal);
if (!statusVal.equals(newVal)) {
logResp.getStatus().getStatusCode().setValue(statusVal);
}
if (debug.messageEnabled()) {
debug.message("SingleLogoutManager.sendLogoutRes:" + "(SAML2) location=" + location + " orig status=" + statusVal + ", new status=" + newVal + ", orig relay=" + origRelayState + ", realm=" + realm + ", idpEntityID=" + idpEntityID + ", spEntityID=" + spEntityID);
}
LogoutUtil.sendSLOResponse(response, logResp, location, origRelayState, realm, idpEntityID, SAML2Constants.IDP_ROLE, spEntityID);
} catch (SAML2Exception ex) {
debug.error("SingleLogoutManager.sendLogoutResponse:saml2", ex);
throw new IOException(ex.getMessage());
}
} else if (protocol.equals(SingleLogoutManager.IDFF)) {
boolean failed = false;
String logoutDoneURL = null;
try {
debug.message("SingleLogoutManager.sendLogoutResp: IDFF");
IDFFMetaManager metaManager = FSUtils.getIDFFMetaManager();
ProviderDescriptorType descriptor = metaManager.getSPDescriptor(realm, spEntityID);
String retURL = descriptor.getSingleLogoutServiceReturnURL();
Element elem = XMLUtils.toDOMDocument(logoutResponseXML, SingleLogoutManager.debug).getDocumentElement();
FSLogoutResponse responseLogout = new FSLogoutResponse(elem);
BaseConfigType hostedConfig = metaManager.getIDPDescriptorConfig(realm, idpEntityID);
logoutDoneURL = FSServiceUtils.getLogoutDonePageURL(request, hostedConfig, null);
Status status = responseLogout.getStatus();
String statusVal = status.getStatusCode().getValue();
String newVal = getNewStatusCode(currentStatus, statusVal);
if (!statusVal.equals(newVal)) {
com.sun.identity.saml.protocol.StatusCode statCode = new com.sun.identity.saml.protocol.StatusCode(newVal);
com.sun.identity.saml.protocol.Status stat = new com.sun.identity.saml.protocol.Status(statCode);
responseLogout.setStatus(stat);
}
if (debug.messageEnabled()) {
debug.message("SingleLogoutManager.sendLogoutRes:" + "(IDFF) orig status=" + statusVal + ", new status=" + newVal + ", orig relay=" + origRelayState + ", logout done URL=" + logoutDoneURL + ", realm=" + realm + ", idpEntityID=" + idpEntityID + ", spEntityID=" + spEntityID);
}
String urlEncodedResponse = responseLogout.toURLEncodedQueryString();
// Sign the request querystring
if (FSServiceUtils.isSigningOn()) {
String certAlias = IDFFMetaUtils.getFirstAttributeValueFromConfig(hostedConfig, IFSConstants.SIGNING_CERT_ALIAS);
if (certAlias == null || certAlias.length() == 0) {
if (debug.messageEnabled()) {
debug.message("SingleLogoutManager.sendLogoutRes:" + "signSAMLRequest couldn't obtain cert alias.");
}
throw new SAMLResponderException(FSUtils.bundle.getString(IFSConstants.NO_CERT_ALIAS));
} else {
urlEncodedResponse = FSSignatureUtil.signAndReturnQueryString(urlEncodedResponse, certAlias);
}
}
StringBuffer redirectURL = new StringBuffer();
redirectURL.append(retURL);
if (retURL.indexOf(IFSConstants.QUESTION_MARK) == -1) {
redirectURL.append(IFSConstants.QUESTION_MARK);
} else {
redirectURL.append(IFSConstants.AMPERSAND);
}
redirectURL.append(urlEncodedResponse);
if (debug.messageEnabled()) {
debug.message("SingleLogoutManager.sendResponse " + "for IDFF, url = " + redirectURL.toString());
}
response.sendRedirect(redirectURL.toString());
} catch (FSMsgException ex) {
debug.error("SingleLogoutManager.sendLogoutRes", ex);
failed = true;
} catch (SAMLException ex) {
debug.error("SingleLogoutManager.sendLogoutRes", ex);
failed = true;
;
} catch (IDFFMetaException ex) {
debug.error("SingleLogoutManager.sendLogoutRes", ex);
failed = true;
} catch (IOException ex) {
debug.error("SingleLogoutManager.sendLogoutRes", ex);
failed = true;
}
if (failed) {
FSServiceUtils.returnLocallyAfterOperation(response, logoutDoneURL, false, IFSConstants.LOGOUT_SUCCESS, IFSConstants.LOGOUT_FAILURE);
}
} else if (protocol.equals(SingleLogoutManager.WS_FED)) {
debug.message("SingleLogoutManager.sendLogoutResponse: WSFED");
if (origRelayState != null) {
response.sendRedirect(origRelayState);
} else {
response.getWriter().print("Logout DONE.");
}
} else {
// should never come here
debug.error("SingleLogoutManager.sendLogoutResponse: invalid" + " protocol : " + protocol);
}
}
cleanupParameters(relayState);
return;
}
use of com.sun.identity.saml2.protocol.LogoutResponse 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.saml2.protocol.LogoutResponse in project OpenAM by OpenRock.
the class IDPSingleLogout method getLogoutStatus.
private static int getLogoutStatus(LogoutResponse logoutRes) {
StatusCode statusCode = logoutRes.getStatus().getStatusCode();
String code = statusCode.getValue();
if (code.equals(SAML2Constants.SUCCESS)) {
return SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
} else {
return SingleLogoutManager.LOGOUT_FAILED_STATUS;
}
}
use of com.sun.identity.saml2.protocol.LogoutResponse in project OpenAM by OpenRock.
the class IDPSingleLogout method processLogoutResponse.
static boolean processLogoutResponse(HttpServletRequest request, HttpServletResponse response, LogoutResponse logoutRes, String relayState, String metaAlias, String idpEntityID, String spEntityID, String realm, String binding) throws SAML2Exception, SessionException {
// use the cache to figure out which session index is in question
// and then use the cache to see if any more SPs to send logout request
// if yes, send one
// if no, do local logout and send response back to original requesting
// SP (this SP name should be remembered in cache)
Object session = sessionProvider.getSession(request);
String tokenID = sessionProvider.getSessionID(session);
String idpSessionIndex = IDPSSOUtil.getSessionIndex(session);
if (idpSessionIndex == null) {
if (debug.messageEnabled()) {
debug.message("No SP session participant(s)");
}
MultiProtocolUtils.invalidateSession(session, request, response, SingleLogoutManager.SAML2);
return false;
}
IDPSession idpSession = IDPCache.idpSessionsByIndices.get(idpSessionIndex);
if (idpSession == null) {
if (debug.messageEnabled()) {
debug.message("IDPSLO.processLogoutResponse : " + "IDP Session with session index " + idpSessionIndex + " already removed.");
}
try {
if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
}
} catch (SAML2TokenRepositoryException se) {
debug.error("IDPSingleLogout.processLogoutRequest: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
}
IDPCache.authnContextCache.remove(idpSessionIndex);
MultiProtocolUtils.invalidateSession(session, request, response, SingleLogoutManager.SAML2);
return false;
}
if (debug.messageEnabled()) {
debug.message("idpSessionIndex=" + idpSessionIndex);
}
List<NameIDandSPpair> list = idpSession.getNameIDandSPpairs();
debug.message("idpSession.getNameIDandSPpairs()=" + list);
if (list.isEmpty()) {
return sendLastResponse(idpSession, logoutRes, request, response, idpSessionIndex, session, realm, idpEntityID, relayState);
} else {
// send Next Requests
Iterator<NameIDandSPpair> it = list.iterator();
while (it.hasNext()) {
NameIDandSPpair pair = it.next();
it.remove();
spEntityID = pair.getSPEntityID();
removeTransientNameIDFromCache(pair.getNameID());
Map paramsMap = new HashMap(request.getParameterMap());
paramsMap.put(SAML2Constants.ROLE, SAML2Constants.IDP_ROLE);
List<SingleLogoutServiceElement> slosList = getSPSLOServiceEndpoints(realm, spEntityID);
List extensionsList = LogoutUtil.getExtensionsList(request.getParameterMap());
SPSSOConfigElement spConfig = sm.getSPSSOConfig(realm, spEntityID);
//When processing a logout response we must ensure that we try to use the original logout request
//binding to make sure asynchronous bindings have precedence over synchronous bindings.
SingleLogoutServiceElement logoutEndpoint = LogoutUtil.getMostAppropriateSLOServiceLocation(slosList, idpSession.getOriginatingLogoutRequestBinding());
if (logoutEndpoint == null) {
continue;
}
StringBuffer requestID = LogoutUtil.doLogout(metaAlias, spEntityID, extensionsList, logoutEndpoint, relayState, idpSessionIndex, pair.getNameID(), request, response, paramsMap, spConfig);
String bindingUsed = logoutEndpoint.getBinding();
if (bindingUsed.equals(SAML2Constants.HTTP_REDIRECT) || bindingUsed.equals(SAML2Constants.HTTP_POST)) {
String requestIDStr = requestID.toString();
if (debug.messageEnabled()) {
debug.message("IDPSingleLogout.processLogoutRequest: requestIDStr = " + requestIDStr + "\nbinding = " + bindingUsed);
}
if (requestIDStr != null && requestIDStr.length() != 0) {
idpSession.setPendingLogoutRequestID(requestIDStr);
}
return true;
}
}
//response.
return sendLastResponse(idpSession, logoutRes, request, response, idpSessionIndex, session, realm, idpEntityID, relayState);
}
}
Aggregations