/** * 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 * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * 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: FSSSOBrowserArtifactProfileHandler.java,v 1.6 2008/12/19 06:50:46 exu Exp $ * */ /* * Portions Copyrighted 2013 ForgeRock, Inc. */ package com.sun.identity.federation.services.fednsso; import com.sun.identity.federation.services.FSAssertionManager; import com.sun.identity.federation.services.util.FSServiceUtils; import com.sun.identity.federation.message.FSResponse; import com.sun.identity.federation.message.FSSAMLRequest; import com.sun.identity.federation.message.FSAuthnRequest; import com.sun.identity.federation.message.FSAssertionArtifact; import com.sun.identity.federation.common.FSUtils; import com.sun.identity.federation.common.FSException; import com.sun.identity.federation.common.IFSConstants; import com.sun.identity.federation.common.LogUtil; import com.sun.identity.federation.jaxb.entityconfig.BaseConfigType; import com.sun.identity.federation.key.KeyUtil; import com.sun.identity.liberty.ws.meta.jaxb.SPDescriptorType; import com.sun.identity.plugin.session.SessionException; import com.sun.identity.plugin.session.SessionManager; import com.sun.identity.saml.xmlsig.XMLSignatureManager; import com.sun.identity.saml.assertion.Assertion; import com.sun.identity.saml.assertion.NameIdentifier; import com.sun.identity.saml.assertion.Conditions; import com.sun.identity.saml.assertion.AudienceRestrictionCondition; import com.sun.identity.saml.protocol.StatusCode; import com.sun.identity.saml.protocol.Request; import com.sun.identity.saml.protocol.Status; import com.sun.identity.saml.protocol.AssertionArtifact; import com.sun.identity.saml.common.SAMLException; import com.sun.identity.saml.common.SAMLResponderException; import com.sun.identity.saml.common.SAMLUtils; import com.sun.identity.shared.encode.URLEncDec; import org.forgerock.openam.utils.ClientUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.soap.SOAPMessage; import java.security.cert.X509Certificate; import java.util.Set; import java.util.Iterator; import java.util.List; import java.util.ArrayList; import java.util.logging.Level; import org.w3c.dom.Element; import org.w3c.dom.Document; /** * IDP single sign on service handler handles browser artifact * profile. */ public class FSSSOBrowserArtifactProfileHandler extends FSSSOAndFedHandler { private Element samlRequestElement = null; private SOAPMessage soapMsg = null; /** * Sets SOAP message. * @param msg SOAPMessage object */ public void setSOAPMessage(SOAPMessage msg) { soapMsg = msg; } /** * Sets SAML request element. * @param root SAML request element */ public void setSAMLRequestElement(Element root) { FSUtils.debug.message( "FSBrowserArtifactConsumerHandler.setSAMLRequestElement: Called"); samlRequestElement = root; } protected FSSSOBrowserArtifactProfileHandler() { } /** * Constructor. * @param request HttpServletRequest object * @param response HttpServletResponse object * @param authnRequest authentication request * @param spDescriptor SP's provider descriptor * @param spConfig SP's extended meta config * @param spEntityId SP's entity id * @param relayState where to go after single sign on is done */ public FSSSOBrowserArtifactProfileHandler( HttpServletRequest request, HttpServletResponse response, FSAuthnRequest authnRequest, SPDescriptorType spDescriptor, BaseConfigType spConfig, String spEntityId, String relayState) { super(request, response, authnRequest, spDescriptor, spConfig, spEntityId, relayState); } /** * Constructor. * @param request HttpServletRequest object * @param response HttpServletResponse object * @param samlRequest Request object that contains artifact */ public FSSSOBrowserArtifactProfileHandler( HttpServletRequest request, HttpServletResponse response, Request samlRequest ) { this.request = request; this.response = response; //this.samlRequest = samlRequest; } /** * Processes authentication request. * @param authnRequest authentication request * @param bPostAuthn true indicates it's post authentication; * false indicates it's pre authentication. */ @Override public void processAuthnRequest( FSAuthnRequest authnRequest, boolean bPostAuthn) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler.processAuthnRequest: Called"); try { if (bPostAuthn){ if (processPostAuthnSSO(authnRequest)){ if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler." + "processAuthnRequest: AuthnRequest Processing" + "successful"); } } else { if (FSUtils.debug.warningEnabled()) { FSUtils.debug.warning( "FSSSOBrowserArtifactProfileHandler." + "processAuthnRequest: AuthnRequest Processing " + "failed"); } String[] data = { FSUtils.bundle.getString("AuthnRequestProcessingFailed") }; LogUtil.error(Level.INFO, LogUtil.AUTHN_REQUEST_PROCESSING_FAILED, data, ssoToken); sendSAMLArtifacts(null); } } else { boolean authnRequestSigned = spDescriptor.isAuthnRequestsSigned(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "processAuthnRequest: ProviderID : " + spEntityId + " AuthnRequestSigned : " + authnRequestSigned); } if (FSServiceUtils.isSigningOn()){ if (authnRequestSigned){ if (!verifyRequestSignature(authnRequest)){ FSUtils.debug.error( "FSSSOBrowserArtifactProfileHandler." + "processAuthnRequest: " + "AuthnRequest Signature Verification Failed"); String[] data = { FSUtils.bundle.getString( "signatureVerificationFailed") }; LogUtil.error(Level.INFO, LogUtil.SIGNATURE_VERIFICATION_FAILED, data, ssoToken); sendSAMLArtifacts(null); return; } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler." + "processAuthnRequest: " + "AuthnRequest Signature Verified"); } } } } if (processPreAuthnSSO(authnRequest)){ if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler." + "processAuthnRequest: AuthnRequest Processing " + " successful"); } } else { if (FSUtils.debug.warningEnabled()) { FSUtils.debug.warning( "FSSSOBrowserArtifactProfileHandler." + "processAuthnRequest: AuthnRequest Processing " + "failed"); } String[] data = { FSUtils.bundle.getString("AuthnRequestProcessingFailed") }; LogUtil.error(Level.INFO, LogUtil.AUTHN_REQUEST_PROCESSING_FAILED, data, ssoToken); sendSAMLArtifacts(null); } } } catch(Exception e){ FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "processAuthnRequest: Exception Occured: ", e); sendSAMLArtifacts(null); } } /** * Processes request with artifacts. * @param samlRequest FSSAMLRequest object * @return FSResponse object */ @Override public FSResponse processSAMLRequest(FSSAMLRequest samlRequest) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler.processSAMLRequest: Called"); try { return createSAMLResponse(samlRequest); } catch(Exception e){ FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "processSAMLRequest: Fatal error, " + "cannot create status or response: ", e); return null; } } private FSResponse createSAMLResponse(FSSAMLRequest samlRequest) throws FSException { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler.createSAMLResponse: Called"); FSResponse retResponse = null; String respID= FSUtils.generateID(); String inResponseTo= samlRequest.getRequestID(); List contents = new ArrayList(); String message = null; int length; Status status; String remoteAddr = ClientUtils.getClientIPAddress(request); String respPrefix = FSUtils.bundle.getString("responseLogMessage") + " " + remoteAddr; int reqType = samlRequest.getContentType(); if (reqType == Request.NOT_SUPPORTED) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: " + "Found element in the request which are not supported"); } message = FSUtils.bundle.getString("unsupportedElement"); try { status = new Status( new StatusCode("samlp:Responder"),message, null); retResponse = new FSResponse( respID, inResponseTo, status, contents); retResponse.setMinorVersion(samlRequest.getMinorVersion()); } catch( SAMLException se ) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: " + "Fatal error, cannot create status or response: ", se); } if (LogUtil.isAccessLoggable(Level.FINER)) { String[] data = { respPrefix , retResponse.toString() }; LogUtil.access(Level.FINER,LogUtil.CREATE_SAML_RESPONSE,data); } else { String[] data = { respPrefix, FSUtils.bundle.getString("responseID") + "=" + retResponse.getResponseID() + "," + FSUtils.bundle.getString("inResponseTo") + "=" + retResponse.getInResponseTo()}; LogUtil.access(Level.INFO,LogUtil.CREATE_SAML_RESPONSE,data); } return retResponse; } FSAssertionManager am = null; try { am = FSAssertionManager.getInstance(metaAlias); } catch(FSException se ) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Cannot instantiate " + "FSAssertionManager"); } message = se.getMessage(); try { status = new Status( new StatusCode("samlp:Responder"), message, null); retResponse = new FSResponse( respID,inResponseTo, status, contents); retResponse.setMinorVersion(samlRequest.getMinorVersion()); } catch( SAMLException sse ) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: " + "Fatal error, cannot create status or response: ", sse); } if (LogUtil.isAccessLoggable(Level.FINER)) { String[] data = { respPrefix , retResponse.toString() }; LogUtil.access(Level.FINER,LogUtil.CREATE_SAML_RESPONSE,data); } else { String[] data = { respPrefix, FSUtils.bundle.getString("responseID") + "=" + retResponse.getResponseID() + "," + FSUtils.bundle.getString("inResponseTo") + "=" + retResponse.getInResponseTo()}; LogUtil.access(Level.INFO,LogUtil.CREATE_SAML_RESPONSE,data); } return retResponse; } List artifacts = null; List assertions = new ArrayList(); if (reqType == Request.ASSERTION_ARTIFACT) { artifacts = samlRequest.getAssertionArtifact(); length = artifacts.size(); // ensure that all the artifacts have the same sourceID String sourceID = null; String providerID = null; AssertionArtifact art = null; for (int j = 0; j < length; j++) { art =(AssertionArtifact)artifacts.get(j); if (sourceID != null) { if (!sourceID.equals(art.getSourceID())) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Artifacts not from " + "the same source"); } message = FSUtils.bundle.getString("mismatchSourceID"); try { /** * Need a second level status for the federation * does not exist. */ status = new Status( new StatusCode("samlp:Requester", new StatusCode( IFSConstants.FEDERATION_NOT_EXISTS_STATUS, null)), message, null); retResponse = new FSResponse(respID, inResponseTo, status, contents); retResponse.setMinorVersion( samlRequest.getMinorVersion()); } catch( SAMLException ex ) { FSUtils.debug.error( "FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Fatal error, " + "cannot create status or response: ", ex); } if (LogUtil.isAccessLoggable(Level.FINER)) { String[] data = { respPrefix , retResponse.toString() }; LogUtil.access(Level.FINER, LogUtil.CREATE_SAML_RESPONSE, data); } else { String[] data = { respPrefix, FSUtils.bundle.getString("responseID") + "=" + retResponse.getResponseID() + "," + FSUtils.bundle.getString("inResponseTo") + "=" + retResponse.getInResponseTo()}; LogUtil.access( Level.INFO, LogUtil.CREATE_SAML_RESPONSE,data); } return retResponse; } else { //sourceids are equal continue; } } else {// sourceID == null sourceID = art.getSourceID(); } } // while loop to go through artifacts to check for sourceID if (art != null){ try { providerID = am.getDestIdForArtifact(art); } catch(FSException ex){ FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: FSException Occured while " + "retrieving sp's providerID for the artifact: ", ex); providerID = null; } if (providerID == null){ FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: " + "artifact received does not correspond to any SP"); message = FSUtils.bundle.getString("invalidSource"); try { /** * Need a second level status for the federation * does not exist. */ /** * First, let's check we haven't recorded a status * beforehand (by another call) related to this * artifact. If so, use it. */ Status sorig = am.getErrorStatus( art ); if ( sorig != null ) { status = sorig; } else { status = new Status( new StatusCode("samlp:Requester", new StatusCode( IFSConstants.FEDERATION_NOT_EXISTS_STATUS, null)), message, null); } retResponse = new FSResponse( respID,inResponseTo, status, contents); retResponse.setMinorVersion( samlRequest.getMinorVersion()); return retResponse; } catch( SAMLException sse ) { FSUtils.debug.error( "FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse:Fatal error, " + "cannot create status or response: ", sse); return null; } //return error response } else { try { if (!metaManager.isTrustedProvider( realm, hostedEntityId,providerID)) { FSUtils.debug.error( "FSSSOAndFedHandler.processAuthnRequest: " + "RemoteProvider is not trusted"); message = FSUtils.bundle.getString( "AuthnRequestProcessingFailed"); status = new Status( new StatusCode("samlp:Requester"), message, null); retResponse = new FSResponse( respID, inResponseTo, status, contents); retResponse.setMinorVersion( samlRequest.getMinorVersion()); return retResponse; } spDescriptor = metaManager.getSPDescriptor( realm, providerID); spEntityId = providerID; remoteAddr = providerID; } catch(Exception ae){ FSUtils.debug.error( "FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: " + "FSAllianceManagementException " + "Occured while getting" , ae); message = ae.getMessage(); try { status = new Status( new StatusCode("samlp:Requester"), message, null); retResponse = new FSResponse( respID,inResponseTo, status, contents); retResponse.setMinorVersion( samlRequest.getMinorVersion()); return retResponse; } catch( SAMLException sse ) { FSUtils.debug.error( "FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse:Fatal error, " + "cannot create status or response: ", sse); return null; } } } //Verify signature if (FSServiceUtils.isSigningOn()){ if (!verifySAMLRequestSignature( samlRequestElement, soapMsg)) { FSUtils.debug.error( "FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: " + "SAMLRequest signature verification failed"); message = FSUtils.bundle.getString( "signatureVerificationFailed"); try { status = new Status( new StatusCode("samlp:Requester"), message, null); retResponse = new FSResponse( respID, inResponseTo, status, contents); retResponse.setMinorVersion( samlRequest.getMinorVersion()); return retResponse; } catch( SAMLException sse ) { FSUtils.debug.error( "FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse:Fatal error, " + "cannot create status or response: " + sse.getMessage()); } } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOBrowserArtProfileHandler.createSAMLResp:" + " SAMLRequest signature verified"); } } } //end signature verification } else { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: No artifact found in samlRequest"); message = FSUtils.bundle.getString("missingArtifact"); try { status = new Status( new StatusCode("samlp:Requester"), message, null); retResponse = new FSResponse( respID,inResponseTo, status, contents); retResponse.setMinorVersion(samlRequest.getMinorVersion()); return retResponse; } catch( SAMLException sse ) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse:Fatal error, " + "cannot create status or response: ", sse); return null; } } for (int i = 0; i < length; i++) { AssertionArtifact artifact =(AssertionArtifact) artifacts.get(i); Assertion assertion = null; try { assertion = am.getAssertion(artifact, spEntityId); } catch(FSException e ) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler.createSAML" + "Response:could not find matching assertion:", e); } message = e.getMessage(); try { status = new Status( new StatusCode("samlp:Success"), message, null); retResponse = new FSResponse( respID,inResponseTo, status, contents); retResponse.setMinorVersion( samlRequest.getMinorVersion()); } catch( SAMLException sse ) { FSUtils.debug.error( "FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse:Fatal error, " + "cannot create status or response: ", sse); } if (LogUtil.isAccessLoggable(Level.FINER)) { String[] data = { respPrefix , retResponse.toString() }; LogUtil.access( Level.FINER,LogUtil.CREATE_SAML_RESPONSE,data); } else { String[] data = { respPrefix, FSUtils.bundle.getString("responseID") + "=" + retResponse.getResponseID() + "," + FSUtils.bundle.getString("inResponseTo") + "=" + retResponse.getInResponseTo()}; LogUtil.access( Level.INFO, LogUtil.CREATE_SAML_RESPONSE,data); } return retResponse; } if (assertion != null) { assertions.add(i,assertion); } } } int assertionSize = assertions.size(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: found " + assertionSize + "assertions."); } // check that the target restriction condition // inside the assertion has the calling host's address in it. for (int i = 0; i < assertionSize; i++) { Assertion assn = (Assertion)assertions.get(i); Conditions conds = assn.getConditions(); Set trcs = conds.getAudienceRestrictionCondition(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: checking to see if assertions" + " are for host:" + remoteAddr); } if (trcs != null && !trcs.isEmpty()) { Iterator trcsIterator = trcs.iterator(); while (trcsIterator.hasNext()) { if (!((AudienceRestrictionCondition)trcsIterator.next()) .containsAudience(remoteAddr)) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: removing TRC not" + "meant for this host"); } assertions.remove(assn); } } } } assertionSize = assertions.size(); if (assertionSize == 0) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Matching Assertions(s) not " + "created for this host"); } message = FSUtils.bundle.getString("mismatchDest"); try { status = new Status(new StatusCode("samlp:Success"), message, null); retResponse = new FSResponse( respID, inResponseTo, status, contents); retResponse.setMinorVersion(samlRequest.getMinorVersion()); } catch( SAMLException se ) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Fatal error, " + "cannot create status or response:", se); } if (LogUtil.isAccessLoggable(Level.FINER)) { String[] data = { respPrefix , retResponse.toString() }; LogUtil.access(Level.FINER,LogUtil.CREATE_SAML_RESPONSE,data); } else { String[] data = { respPrefix, FSUtils.bundle.getString("responseID") + "=" + retResponse.getResponseID() + "," + FSUtils.bundle.getString("inResponseTo") + "=" + retResponse.getInResponseTo()}; LogUtil.access( Level.INFO, LogUtil.CREATE_SAML_RESPONSE,data); } return retResponse; } if (reqType == Request.ASSERTION_ARTIFACT) { if (assertions.size() == artifacts.size()) { message = null; if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Matching Assertion found"); } try { status = new Status( new StatusCode("samlp:Success"), message, null); retResponse = new FSResponse( respID, inResponseTo, status, assertions); retResponse.setMinorVersion(samlRequest.getMinorVersion()); } catch( SAMLException se ) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Fatal error, " + "cannot create status or response:", se); return null; } catch(Exception e ) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Fatal error, " + "cannot create status or response:", e); return null; } if (LogUtil.isAccessLoggable(Level.FINER)) { String[] data = { respPrefix , retResponse.toString() }; LogUtil.access( Level.FINER,LogUtil.CREATE_SAML_RESPONSE, data); } else { String[] data = { respPrefix, FSUtils.bundle.getString("responseID") + "=" + retResponse.getResponseID() + "," + FSUtils.bundle.getString("inResponseTo") + "=" + retResponse.getInResponseTo()}; LogUtil.access( Level.INFO, LogUtil.CREATE_SAML_RESPONSE,data); } return retResponse; } else { message = FSUtils.bundle.getString("unequalMatch"); try { status = new Status( new StatusCode("samlp:Success"), message, null); retResponse = new FSResponse( respID, inResponseTo, status, assertions); retResponse.setMinorVersion(samlRequest.getMinorVersion()); } catch( SAMLException se ) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Fatal error, " + "cannot create status or response:", se); } if (LogUtil.isAccessLoggable(Level.FINER)) { String[] data = { respPrefix , retResponse.toString() }; LogUtil.access( Level.FINER,LogUtil.CREATE_SAML_RESPONSE,data); } else { String[] data = { respPrefix, FSUtils.bundle.getString("responseID") + "=" + retResponse.getResponseID() + "," + FSUtils.bundle.getString("inResponseTo") + "=" + retResponse.getInResponseTo()}; LogUtil.access( Level.INFO, LogUtil.CREATE_SAML_RESPONSE,data); } return retResponse; } } else { // build response for all the other type of request try { message = null; status = new Status( new StatusCode("samlp:Success"), message, null); retResponse = new FSResponse( respID, inResponseTo, status, assertions); retResponse.setMinorVersion(samlRequest.getMinorVersion()); } catch( SAMLException se ) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLResponse: Fatal error, " + "cannot create status or response:", se); } } if (LogUtil.isAccessLoggable(Level.FINER)) { String[] data = { respPrefix , retResponse.toString() }; LogUtil.access(Level.FINER,LogUtil.CREATE_SAML_RESPONSE, data); } else { String[] data = { respPrefix, FSUtils.bundle.getString("responseID") + "=" + retResponse.getResponseID() + "," + FSUtils.bundle.getString("inResponseTo") + "=" + retResponse.getInResponseTo()}; LogUtil.access(Level.INFO, LogUtil.CREATE_SAML_RESPONSE,data); } return retResponse; } /** * Generates artifact and sends it to SP. * @return true always. */ @Override protected boolean doSingleSignOn( Object ssoToken, String inResponseTo, NameIdentifier opaqueHandle, NameIdentifier idpOpaqueHandle ) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler.doSingleSignOn: Called"); this.ssoToken = ssoToken; List artList = createSAMLAssertionArtifact(ssoToken, inResponseTo, opaqueHandle, idpOpaqueHandle); sendSAMLArtifacts(artList); return true; } /** * Creates assertion and assertion artifact. */ protected List createSAMLAssertionArtifact( Object ssoToken, String inResponseTo, NameIdentifier userHandle, NameIdentifier idpHandle ) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "createSAMLAssertionArtifact: Called"); } List artifactList = new ArrayList(); try { FSAssertionManager am = FSAssertionManager.getInstance(metaAlias); AssertionArtifact artifact = am.createFSAssertionArtifact( SessionManager.getProvider().getSessionID(ssoToken), realm, spEntityId, userHandle, idpHandle, inResponseTo, authnRequest.getMinorVersion()); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("AssertionArtifact id = " + artifact.toString()); } String artid = artifact.getAssertionArtifact(); artifactList.add(artid); return artifactList; } catch(FSException se) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLAssertionArtifact(0): ", se); return null; } catch(SAMLException se) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLAssertionArtifact(1): ", se); return null; } catch (SessionException se) { FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "createSAMLAssertionArtifact(2): ", se); return null; } } private void sendSAMLArtifacts(List artis) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler.sendSAMLArtifacts: Called"); if (artis == null) { artis = createFaultSAMLArtifact(); } try { String targetURL = FSServiceUtils.getAssertionConsumerServiceURL( spDescriptor, authnRequest.getAssertionConsumerServiceID()); StringBuilder sb = new StringBuilder(1000); if (artis == null || artis.isEmpty()){ if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "sendSAMLArtifacts: Sending null artifact"); } sb.append(IFSConstants.ARTIFACT_NAME_DEFAULT) .append("=") .append("&"); } else { Iterator iter = artis.iterator(); while(iter.hasNext()) { String art = URLEncDec.encode((String)iter.next()); if(FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler." + "sendSAMLArtifacts: " + art); } sb.append(IFSConstants.ARTIFACT_NAME_DEFAULT) .append("=") .append(art) .append("&"); } } StringBuilder tmp = new StringBuilder(1000); if (targetURL.indexOf('?') == -1){ tmp.append(targetURL).append("?"); } else { tmp.append(targetURL).append("&"); } tmp.append(sb.toString()); String relayURL = authnRequest.getRelayState(); if (relayURL != null){ tmp.append(IFSConstants.LRURL) .append("=") .append(URLEncDec.encode(relayURL)); } response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); String redirecto = tmp.toString(); response.setContentType("text/html"); response.setHeader("Location", redirecto); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "sendSAMLArtifacts: Sending artifacts to: " + redirecto); } String[] data = { redirecto }; LogUtil.access(Level.FINER,LogUtil.REDIRECT_TO, data, ssoToken); response.sendRedirect(redirecto); } catch(Exception ex){ FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "sendSAMLArtifacts: ", ex); } } /** * Generates a valid SAML artifact, in response * to a single sign on request for a non federated user. */ private List createFaultSAMLArtifact() { FSUtils.debug.message( "FSSSOBrowserArtifactProfileHandler. In createFaultSAMLArtifacts"); // create assertion id and artifact String handle = SAMLUtils.generateAssertionHandle(); if (handle == null) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "create FaultSAMLArtifacts: couldn't generate assertion " + "handle."); } return null; } try { String sourceSuccinctID = FSUtils.generateSourceID(hostedEntityId); AssertionArtifact art = new FSAssertionArtifact( SAMLUtils.stringToByteArray(sourceSuccinctID), handle.getBytes(IFSConstants.SOURCEID_ENCODING)); List artis = new ArrayList(); artis.add(art.getAssertionArtifact()); FSAssertionManager am = FSAssertionManager.getInstance( metaAlias ); am.setErrStatus( art, noFedStatus ); return artis; } catch(Exception e) { FSUtils.debug.error( "FSBrowserArtifactProfileHandler.createFaultSAMLArtifacts: ", e); return null; } } protected boolean verifySAMLRequestSignature( Element samlRequestElement, SOAPMessage msg ) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "verifySAMLRequestSignature: Called"); } try { X509Certificate cert = KeyUtil.getVerificationCert( spDescriptor, spEntityId, false); if (cert == null) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOBrowserArtifactProfileHandler." + "verifySAMLRequestSignature: couldn't obtain " + "this site's cert."); } throw new SAMLResponderException( FSUtils.bundle.getString(IFSConstants.NO_CERT)); } XMLSignatureManager manager = XMLSignatureManager.getInstance(); Document doc = (Document)FSServiceUtils.createSOAPDOM(msg); return manager.verifyXMLSignature(doc, cert); } catch(Exception e){ FSUtils.debug.error("FSSSOBrowserArtifactProfileHandler." + "verifySAMLRequestSignature: Exception occured while " + "verifying IDP's signature:" , e); return false; } } }