LogoutUtil.java revision 0cd8368ca65c58915ee90bc73d84e65f3da9e120
/**
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: LogoutUtil.java,v 1.16 2009/11/20 21:41:16 exu Exp $
*
*/
/*
* Portions Copyrighted 2012-2013 ForgeRock, Inc.
*/
/**
* This class constructs the <code>LogoutRequest</code> and executes
* the required processing logic for sending <code>LogoutRequest</code>
* from SP to IDP.
*/
public class LogoutUtil {
static {
}
/**
* Builds the <code>LogoutRequest</code> and executes
* the required processing logic for sending <code>LogoutRequest</code>
* from SP to IDP.
*
* @param metaAlias the requester's metaAlais.
* @param recipientEntityID the recipient's entity ID.
* @param recipientSLOList recipient's Single Logout Service location
* URL list.
* @param extensionsList Extension list for request.
* @param binding binding used for this request.
* @param relayState the target URL on successful Single Logout.
* @param sessionIndex sessionIndex of the Assertion generated by the
* Identity Provider or Service Provider.
* @param nameID <code>NameID</code> of the Provider.
* @param response the HttpServletResponse.
* @param paramsMap Map of all other parameters.
* Following parameters names with their respective
* String values are allowed in this paramsMap.
* "realm" - MetaAlias for Service Provider. The format of
* this parameter is /realm_name/SP name.
* "RelayState" - the target URL on successful Single Logout
* "Destination" - A URI Reference indicating the address to
* which the request has been sent.
* "Consent" - Specifies a URI a SAML defined identifier
* known as Consent Identifiers.
* @param config entity base config for basic auth.
*
* @return Logout request ID
*
* @throws SAML2Exception if error initiating request to IDP.
* @throws SessionException if error initiating request to IDP.
*/
public static StringBuffer doLogout(
if (debug.messageEnabled()) {
classMethod + "Entering ..." +
"\nrequesterEntityID=" + requesterEntityID +
"\nrecipientEntityID=" + recipientEntityID +
"\nbinding=" + binding +
"\nrelayState=" + relayState +
"\nsessionIndex=" + sessionIndex);
}
// generate unique request ID
throw new SAML2Exception(
}
// retrieve data from the params map
// destinationURI required if message is signed.
// construct LogoutRequest
try {
} catch (Exception e) {
"Unable to create LogoutRequest : ", e);
throw new SAML2Exception(
}
// set required attributes / elements
// set optional attributes / elements
// use the assertion effective time (in seconds)
if (effectiveTimeStr != null) {
try {
"got effective time from config:" + effectiveTime);
}
} catch (NumberFormatException nfe) {
"Failed to get assertion effective time from " +
"IDP SSO config: ", nfe);
}
}
}
if (extensions != null) {
}
if (sessionIndex != null) {
}
// get recipient's logout service location
// based on binding
"Unable to find the recipient's single logout " +
"service with the binding " + binding);
throw new SAML2Exception(
} else {
"Recipient's single logout service location = " +
location);
location));
}
}
if (debug.messageEnabled()) {
}
try {
response);
null);
} catch (Exception e) {
throw new SAML2Exception(
"errorRedirectingLogoutRequest"));
}
if (debug.messageEnabled()) {
}
if (debug.messageEnabled()) {
}
response);
}
return logoutRequestID;
}
static private void doSLOByHttpRedirect(
// encode the xml string
.append(encodedXML);
// spec states that the relay state MUST NOT exceed 80
// chanracters, need to have some means to pass it when it
// exceeds 80 chars
} else {
}
}
boolean needToSign = false;
} else {
}
if (needToSign == true) {
}
if (debug.messageEnabled()) {
}
}
/**
* Performs SOAP logout, this method will send LogoutResuest to IDP using
* SOAP binding, and process LogoutResponse.
* @param requestID Request id.
* @param sloRequest a string representation of LogoutRequest.
* @param sloURL SOAP logout URL on IDP side.
* @param realm a string representation of LogoutRequest.
* @param hostEntity host entity is sending the request.
* @param hostRole SOAP logout URL on IDP side.
* @throws SAML2Exception if logout failed.
* @throws SessionException if logout failed.
*/
private static void doSLOBySOAP(
if (debug.messageEnabled()) {
}
try {
true);
} catch (SOAPException se) {
}
// get the LogoutResponse element from SOAP message
// invoke SPAdapter for preSingleLogoutProcess : SP initiated SOAP
}
if (sloResponse == null) {
"nullLogoutResponse"));
}
if (debug.messageEnabled()) {
"LogoutResponse without SOAP envelope:\n" +
}
hostRole);
if (debug.messageEnabled()) {
}
if (success == false) {
if (fedletAdapter != null) {
}
}
} else {
// invoke SPAdapter for postSLOSuccess : SP inited SOAP
if (fedletAdapter != null) {
}
} else {
}
}
}
}
throws SAML2Exception {
boolean success = false;
if (debug.messageEnabled()) {
"LogoutResponse inResponseTo matches LogoutRequest ID");
}
} else {
"LogoutResponse inResponseTo does not match Request ID.");
"inResponseToNoMatch"));
}
success = true;
} else {
if (debug.messageEnabled()) {
"return code : " + retCode);
}
success = false;
}
return success;
}
if (debug.messageEnabled()) {
"remoteLogoutURL = " + remoteLogoutURL);
}
try {
// get the LogoutResponse element from SOAP message
"LogoutResponse");
if (debug.messageEnabled()) {
}
}
return null;
}
if (statusDetail == null) {
return null;
}
return null;
}
}
}
return sessionIndexList;
}
try {
}
}
} catch (SAML2Exception e) {
}
}
/**
* Gets Single Logout Service location URL.
*
* @param sloList list of configured <code>SingleLogoutElement</code>.
* @param desiredBinding desired binding of SingleLogout.
* @return url of desiredBinding.
*/
public static String getSLOServiceLocation(
"LogoutUtil.getSLOserviceLocation: ";
if (debug.messageEnabled()) {
"Number of single logout services = " +
n);
}
for (int i=0; i<n; i++) {
}
if (debug.messageEnabled()) {
"Single logout service binding = " +
binding);
}
if (debug.messageEnabled()) {
"Found the single logout service "+
"with the desired binding");
}
break;
}
}
return location;
}
/**
* Gets Single Logout Response Service location URL.
*
* @param sloList list of configured <code>SingleLogoutElement</code>.
* @param desiredBinding desired binding of SingleLogout.
* @return url of desiredBinding.
*/
public static String getSLOResponseServiceLocation(
"LogoutUtil.getSLOResponseServiceLocation: ";
if (debug.messageEnabled()) {
"Number of single logout services = " +
n);
}
for (int i=0; i<n; i++) {
}
if (debug.messageEnabled()) {
"Single logout service binding = " +
binding);
}
if (debug.messageEnabled()) {
"Found the single logout service "+
"with the desired binding");
}
break;
}
}
return resLocation;
}
/* Creates Extensions */
}
return extensions;
}
/**
* Builds the <code>LogoutResponse</code> to be sent to IDP.
*
* @param status status of the response.
* @param inResponseTo inResponseTo.
* @param issuer issuer of the response, which is SP.
* @param realm inResponseTo.
* @param hostRole issuer of the response, which is SP.
* @param remoteEntity will get this response.
*
* @return <code>LogoutResponse</code>
*
*/
public static LogoutResponse generateResponse(
}
try {
} catch (SAML2Exception e) {
}
return logoutResponse;
}
/**
* Sign LogoutRequest.
*
* @param sloRequest SLO request will be signed.
* @param realm realm of host entity.
* @param hostEntity entity ID of host entity.
* @param hostEntityRole role of host entity.
* @param remoteEntity entity ID of remote host entity.
* @throws SAML2Exception if error in signing the request.
*/
throws SAML2Exception {
hostEntityRole, remoteEntity, false);
}
boolean includeCert)
throws SAML2Exception {
boolean needRequestSign = false;
} else {
}
if (needRequestSign == false) {
if (debug.messageEnabled()) {
}
return;
}
String encryptedKeyPass = SAML2Utils.getSigningCertEncryptedKeyPass(realm, hostEntity, hostEntityRole);
if (debug.messageEnabled()) {
+ sloRequest.toXMLString(true, true));
}
}
} else {
}
if (includeCert) {
}
if (signingKey != null) {
} else {
throw new SAML2Exception(
}
if (debug.messageEnabled()) {
+ sloRequest.toXMLString(true, true));
}
}
/**
* Verify the signature in LogoutRequest.
*
* @param sloRequest SLO request will be verified.
* @param realm realm of host entity.
* @param remoteEntity entity ID of remote host entity.
* @param hostEntity entity ID of host entity.
* @param hostEntityRole role of host entity.
* @return returns true if signature is valid.
* @throws SAML2Exception if error in verifying the signature.
* @throws SessionException if error in verifying the signature.
*/
throws SAML2Exception, SessionException {
boolean needVerifySignature =
if (needVerifySignature == false) {
if (debug.messageEnabled()) {
}
return true;
}
if (debug.messageEnabled()) {
}
boolean valid = false;
} else {
}
if (signingCert != null) {
if (debug.messageEnabled()) {
}
} else {
throw new SAML2Exception(
}
return valid;
}
/**
* Sign LogoutResponse.
*
* @param sloResponse SLO response will be signed.
* @param realm realm of host entity.
* @param hostEntity entity ID of host entity.
* @param hostEntityRole role of host entity.
* @param remoteEntity entity ID of remote host entity.
* @throws SAML2Exception if error in signing the request.
*/
throws SAML2Exception {
hostEntityRole, remoteEntity, false);
}
boolean includeCert)
throws SAML2Exception {
boolean needSignResponse = false;
} else {
}
if (needSignResponse == false) {
if (debug.messageEnabled()) {
"SLOResponse doesn't need to be signed.");
}
return;
}
String encryptedKeyPass = SAML2Utils.getSigningCertEncryptedKeyPass(realm, hostEntity, hostEntityRole);
if (debug.messageEnabled()) {
}
}
} else {
}
if (includeCert) {
}
if (signingKey != null) {
} else {
throw new SAML2Exception(
}
}
/**
* Verify the signature in LogoutResponse.
*
* @param sloResponse SLO response will be verified.
* @param realm realm of host entity.
* @param remoteEntity entity ID of remote host entity.
* @param hostEntity entity ID of host entity.
* @param hostEntityRole role of host entity.
* @return returns true if signature is valid.
* @throws SAML2Exception if error in verifying the signature.
* @throws SessionException if error in verifying the signature.
*/
throws SAML2Exception, SessionException {
boolean needVerifySignature =
if (needVerifySignature == false) {
if (debug.messageEnabled()) {
"SLOResponse doesn't need to be verified.");
}
return true;
}
boolean valid = false;
} else {
}
if (signingCert != null) {
if (debug.messageEnabled()) {
}
} else {
throw new SAML2Exception(
}
return valid;
}
throws SAML2Exception, SessionException {
boolean needEncryptIt = false;
} else {
}
if (needEncryptIt == false) {
if (debug.messageEnabled()) {
}
return;
}
} else {
}
if (debug.messageEnabled()) {
}
if (encryptInfo == null) {
throw new SAML2Exception(
}
}
throws SAML2Exception {
boolean needDecryptIt =
if (needDecryptIt == false) {
if (debug.messageEnabled()) {
}
}
if (debug.messageEnabled()) {
}
}
}
} else {
}
}
try {
} catch (IOException ioe) {
"errorPostingLogoutResponse"));
}
}
throws SAML2Exception {
try {
// encode the xml string
.append(encodedXML);
}
boolean needToSign = false;
} else {
}
if (needToSign == true) {
}
if (debug.messageEnabled()) {
}
null);
} catch (Exception e) {
"errorRedirectingLogoutResponse"));
}
}
/**
* Returns binding information of SLO Service for remote entity
* from request or meta configuration.
*
* @param request the HttpServletRequest.
* @param metaAlias entityID of hosted entity.
* @param hostEntityRole Role of hosted entity.
* @param remoteEntityID entityID of remote entity.
* @return return true if the processing is successful.
* @throws SAML2Exception if no binding information is configured.
*/
throws SAML2Exception {
try {
if (sloService != null) {
}
}
} catch (SessionException e) {
throw new SAML2Exception(
}
throw new SAML2Exception(
}
return binding;
}
private static SingleLogoutServiceElement getSLOServiceElement(
if (debug.messageEnabled()) {
}
} else {
throw new SAML2Exception(
}
return sloService;
}
/**
* Returns first SingleLogout configuration in an entity under
* the realm.
* @param realm The realm under which the entity resides.
* @param entityId ID of the entity to be retrieved.
* @param binding bind type need to has to be matched.
* @return <code>SingleLogoutServiceElement</code> for the entity or null
* @throws SAML2MetaException if unable to retrieve the first identity
* provider's SSO configuration.
* @throws SessionException invalid or expired single-sign-on session
*/
static public SingleLogoutServiceElement getIDPSLOConfig(
throws SAML2MetaException, SessionException {
if (idpSSODesc == null) {
return null;
}
}
break;
}
}
}
return slo;
}
/**
* Returns first SingleLogout configuration in an entity under
* the realm.
* @param realm The realm under which the entity resides.
* @param entityId ID of the entity to be retrieved.
* @param binding bind type need to has to be matched.
* @return <code>SingleLogoutServiceElement</code> for the entity or null
* @throws SAML2MetaException if unable to retrieve the first identity
* provider's SSO configuration.
* @throws SessionException invalid or expired single-sign-on session
*/
static public SingleLogoutServiceElement getSPSLOConfig(
throws SAML2MetaException, SessionException {
return null;
}
}
break;
}
}
}
return slo;
}
/**
* Returns the extensions list
* @param paramsMap request paramsMap has extensions
* @return <code>List</code> for extensions params
*/
// TODO Get the Extensions list from request parameter
return extensionsList;
}
if (debug.messageEnabled()) {
}
try {
} catch (Exception e) {
"postToTargetFailed"));
}
}
if (samlResponse == null) {
"missingLogoutResponse"));
}
try {
}
}
} catch (Exception e) {
} finally {
try {
if (debug.messageEnabled()) {
ie);
}
}
}
}
"errorGettingLogoutResponse"));
}
return resp;
}
if (samlRequest == null) {
"missingLogoutRequest"));
}
try {
}
}
} catch (Exception e) {
} finally {
try {
if (debug.messageEnabled()) {
ie);
}
}
}
}
"errorGettingLogoutRequest"));
}
return req;
}
}