All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.identity.saml.SAMLClient Maven / Gradle / Ivy

/*
 * 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: SAMLClient.java,v 1.6 2008/08/19 19:11:11 veiming Exp $
 *
 * Portions Copyrighted 2015 ForgeRock AS.
 */

package com.sun.identity.saml; 

import java.io.*;
import java.util.*;
import java.net.URL;
import javax.servlet.http.*;
import com.sun.identity.common.SystemConfigurationUtil;
import com.sun.identity.common.SystemConfigurationException;
import com.sun.identity.plugin.session.SessionException;
import com.sun.identity.plugin.session.SessionManager;
import com.sun.identity.plugin.session.SessionProvider;
import com.sun.identity.saml.common.*;
import com.sun.identity.saml.assertion.*;
import com.sun.identity.saml.protocol.*;
import com.sun.identity.saml.servlet.SAMLSOAPReceiver;
import com.sun.identity.shared.jaxrpc.SOAPClient;
import com.sun.identity.shared.xml.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;

/**
 * The class SAMLClient provides interfaces
 * to do Web and POST profile as specified by SAML specification. It
 * also provides methods to get Assertions based on Artifacts.
 * 
 */

public class SAMLClient {   
    /**
     * This private method is designed to do the SAML Single-Sign-On. 
     * It is called internally by doWebArtifact and doWebPOST methods. 
     * @param request HTTP Servlet Request
     * @param response HTTP Servlet Response
     * @param target the target URL
     * @param service the service name 
     * @exception IOException if an input or output exception occurs when 
     *     redirecting to service URL
     * @exception SAMLException if SAML error occurs during Single-Sign-On.
     */
    private static void doSSO(HttpServletRequest request,
                              HttpServletResponse response, 
                              String target, String service) 
                              throws IOException, SAMLException {
        if (request == null || response == null || target == null) {
            SAMLUtils.debug.error("SAMLClient:Input parameter is null.");
            throw new SAMLException(SAMLUtils.bundle.getString("nullInput")); 
        }
        if ((!service.equals(SAMLConstants.SAML_AWARE_NAMING)) &&
            (!service.equals(SAMLConstants.SAML_POST_NAMING)) &&
            (!service.equals(SAMLConstants.SAML_SOAP_NAMING))) {
            SAMLUtils.debug.error("SAMLClient:illegal naming service name.");
            throw new SAMLException(
                SAMLUtils.bundle.getString("illegalNamingService")); 
        }
        Object ssoToken = null;  
        SessionProvider sessionProvider;
        try {
            sessionProvider = SessionManager.getProvider();
            ssoToken =sessionProvider.getSession(request);
            if (ssoToken == null) {
                SAMLUtils.debug.error("SAMLClient:SSOToken is null.");
                throw new SAMLException( 
                    SAMLUtils.bundle.getString("nullSSOToken")); 
            }
            if (!sessionProvider.isValid(ssoToken)) {
                SAMLUtils.debug.error("SAMLClient:Session is invalid."); 
                throw new SAMLException(
                    SAMLUtils.bundle.getString("invalidSSOToken")); 
            }
        } catch (SessionException se) {
            SAMLUtils.debug.error("SAMLClient", se);
            throw new SAMLException("SAMLClient:doSSO:" + se.getMessage()); 
        }
        URL weburl = null;
        try { 
            URL serverurl = new URL(SAMLServiceManager.getServerURL()); 
            weburl = SystemConfigurationUtil.getServiceURL(service,  
                serverurl.getProtocol(), serverurl.getHost(),
                serverurl.getPort(), serverurl.getPath());  
            
        } catch(SystemConfigurationException ue) {
            SAMLUtils.debug.error("SAMLClient", ue); 
            throw new SAMLException(
                SAMLUtils.bundle.getString("URLNotFoundException")); 
        }
        StringBuffer redirectedurl = new StringBuffer(200); 
        String tname = (String) SAMLServiceManager.
             getAttribute(SAMLConstants.TARGET_SPECIFIER);   
        redirectedurl.append(weburl).append("?").append(tname).append("=").
             append(target);
        response.sendRedirect(redirectedurl.toString()); 
    }             

    /**
     * This method is designed to do the SAML web-browser profile with 
     * Artifact. Once the browser (user) authenticated to OpenAM,
     * it can call this method to complete the single sign on to the
     * target host and be redirected to the specified target site.
     * @param request HTTP Servlet Request
     * @param response HTTP Servlet Response
     * @param target A String representing the target URL
     * @exception IOException if an input or output exception occurs when
     *     redirecting to service URL
     * @exception SAMLException if SAML error occurs during the process 
     * 
     */
    public static void doWebArtifact(HttpServletRequest request, 
                                     HttpServletResponse response, 
                                     String target) 
                                     throws IOException, SAMLException {
        doSSO(request, response, target, SAMLConstants.SAML_AWARE_NAMING);
    }

    /**
     * This method is designed to do the SAML web-browser POST profile. 
     * Once the browser (user) authenticated to OpenAM,
     * it can call this method
     * to complete the single sign on to the target host and be
     * redirected to the target site.
     * @param request HTTP Servlet Request
     * @param response HTTP Servlet Response
     * @param target A String representing the target URL
     * @exception IOException if an input or output exception occurs when
     *     redirecting to service URL
     * @exception SAMLException if SAML error occurs during the process 
     * 
     */
    public static void doWebPOST(HttpServletRequest request,
                                 HttpServletResponse response, 
                                 String target)
                                 throws IOException, SAMLException {
        doSSO(request, response, target, SAMLConstants.SAML_POST_NAMING);
    }
    
    /**
     * This method returns the Assertion for the corresponding artifact.
     * It sends an ArtifactQuery SAML message to the
     * destination identified by the source ID in the artifact and
     * returns the Assertion contained in the SAML response message.
     *
     * @param artifact An AssertionArtifact representing the
     *                 artifact 
     * @return An Assertion corresponding to the artifact
     * @exception IOException if an input or output exception occurs when
     *     connecting to SAML service URL
     * @exception SAMLException if SAML error occurs during the process 
     * 
     */
    public static Assertion getAssertionByArtifact(AssertionArtifact artifact)
        throws IOException, SAMLException {          
        return getAssertionByArtifact(artifact.getAssertionArtifact());
    }

    /**
     * This method returns the Assertion for the corresponding artifact.
     * It sends an ArtifactQuery SAML message to the destination
     * identified by the source ID in the artifact and returns the Assertion
     * contained in the SAML response message.
     *
     * @param artifact A String representing the artifact
     * @return An Assertion corresponding to the artifact
     * @exception IOException if an input or output exception occurs when
     *     connecting to SAML service URL
     * @exception SAMLException if SAML error occurs during the process
     * 
     */
    public static Assertion getAssertionByArtifact(String artifact)
        throws IOException, SAMLException {
        if (artifact == null || artifact.length() == 0) {
            if (SAMLUtils.debug.messageEnabled()) {
                SAMLUtils.debug.message("SAMLClient: input is null.");
            }
            throw new SAMLException(
                SAMLUtils.bundle.getString("nullInput"));
        }
        // first, check if the sourceid contained in the artifact has an entry 
        // in SAML config
        AssertionArtifact aa = new AssertionArtifact(artifact); 
        String sid = aa.getSourceID(); 
        String ssurl = getSamlSoapUrl(sid); 
        // if not, query naming service to get the soap url in case of local 
        URL samlsoap = null; 
        try {
            if (ssurl == null) {
                Map instances= (Map)
                  SAMLServiceManager.getAttribute(SAMLConstants.INSTANCE_LIST); 
                if (instances == null || instances.size() == 0) {
                    throw new SAMLException( 
                        SAMLUtils.bundle.getString("instancemapNull")); 
                }
                String server= (String) instances.get(sid); 
                if (server == null || server.length() == 0) {
                    throw new SAMLException(
                        SAMLUtils.bundle.getString("instanceNotFound")); 
                }
                URL serverurl = new URL(server); 
                samlsoap = SystemConfigurationUtil.getServiceURL(
                    SAMLConstants.SAML_SOAP_NAMING,
                    serverurl.getProtocol(), serverurl.getHost(),
                    serverurl.getPort(), serverurl.getPath());   
            } else {
                samlsoap = new URL(ssurl);
            }
            if (SAMLUtils.debug.messageEnabled()) {
                SAMLUtils.debug.message("SAMLClient:SOAPUrl=" +
                    samlsoap.toString());
            }
        } catch (SystemConfigurationException ue) {
            SAMLUtils.debug.error("SAMLClient", ue);
            throw new SAMLException(
                SAMLUtils.bundle.getString("URLNotFoundException"));
        }
        if (!setLocalFlag(samlsoap)) {
            throw new SAMLException( 
                SAMLUtils.bundle.getString("failSetLocalFlag"));
        }
     
        if (SAMLUtils.debug.messageEnabled()) {
            SAMLUtils.debug.message("SAMLClient:getAssertionByArtifact: " +
                                    "check localFlag : " +
                                     SAMLServiceManager.localFlag);
        }
        String encodedSourceid = (String) SAMLServiceManager.getAttribute(
                                                SAMLConstants.SITE_ID);
        boolean isMySite = sid.equals(encodedSourceid.trim()); 
        if (SAMLServiceManager.localFlag && isMySite)  {
            // if the localFlag is true and the Artifact's source id is 
            // the same as my site_id, (means SAMLClient and AssertionManager 
            // in the same JVM, call AssertionManager directly.
            if (SAMLUtils.debug.messageEnabled()) {
                SAMLUtils.debug.message("SAMLClient:getAssertionByArtifact" +
                                ":call AssertionManager.getAssertion(" +
                                "AssertionArtifact)");      
            }
            AssertionManager assertManager = AssertionManager.getInstance(); 
            Assertion assertion = assertManager.getAssertion(aa);  
            return assertion;
        }
        String[] strarray = new String[1];
        strarray[0]= artifact;
        List asserts = null; 
        if (isMySite && ssurl == null) {
            asserts = artifactQueryHandler(strarray, samlsoap.toString()); 
        } else {
            asserts = artifactQueryHandler(strarray, null); 
        }
        if (asserts == null || asserts.isEmpty()) {
            if (SAMLUtils.debug.messageEnabled()) {
                SAMLUtils.debug.message("SAMLClient:getAssertionByArtifact" +
                                    ":returned assertion list is null.");      
               }
            return null; 
        }
        return ((Assertion) asserts.get(0)); 
    }

    private static String getSamlSoapUrl(String sourceid) {
        String soapurl = null;
        try {
            Map partner = (Map) SAMLServiceManager.getAttribute(
                                                   SAMLConstants.PARTNER_URLS); 
            if (partner == null) {
                SAMLUtils.debug.error("SAMLClient:Partner URL is null.");
                return null;
            }
            SAMLServiceManager.SOAPEntry partnerdest = 
                           (SAMLServiceManager.SOAPEntry) partner.get(sourceid);
            if (partnerdest != null) {
                soapurl = partnerdest.getSOAPUrl(); 
            } else {
                if (SAMLUtils.debug.messageEnabled()) {
                    SAMLUtils.debug.message("SAMLClient: " + sourceid + 
                                            " is not on trusted site list.");
                }
            }
            return soapurl;
        } catch (Exception se) {
            SAMLUtils.debug.error("SAMLClient: ", se);
            return null;
        } 
    }
    
    public static boolean setLocalFlag(URL url) {
        if (url == null) {
            SAMLUtils.debug.error("SAMLClient:setLocalFlag has null input.");
            return false; 
        }
        try {
             // Preload class SAMLSOAPReceiver since it wouldn't be included 
             // in the remote sdk. If the class SAMLSOAPReceiver isn't 
             // presented, we consider it is client application. 
             Class.forName("com.sun.identity.saml.servlet.SAMLSOAPReceiver");
             if (SAMLUtils.debug.messageEnabled()) {
                SAMLUtils.debug.message("in setLocalFlag(), url : " + 
                                        url.toString());
                SAMLUtils.debug.message("SAMLSOAPReceiver.localSAMLServiceID : "
                                        + SAMLSOAPReceiver.localSAMLServiceID);
            }
            if (SAMLSOAPReceiver.localSAMLServiceID != null) { 
                URL samlservice =
                    new URL(SAMLSOAPReceiver.localSAMLServiceID);   
                if ((url.getHost().equalsIgnoreCase(samlservice.getHost())) && 
                    (url.getPort() == samlservice.getPort())) {
                    SAMLServiceManager.localFlag = true;
                    return true; 
                }
            }
        } catch (ClassNotFoundException cnfe) {
          if (SAMLUtils.debug.messageEnabled()) {
              SAMLUtils.debug.message("SAMLClient::setLocalFlag: ",  
                                       cnfe); 
           }
           SAMLServiceManager.localFlag = false; 
           return true; 
        } catch (Exception e) {
            SAMLUtils.debug.error("SAMLClient::setLocalFlag:: ", e);
            return false; 
        }
        SAMLServiceManager.localFlag = false; 
        return true;
    }

    /**
     * This private method takes a SAML request object and returns a SOAPMessage
     * wrapped around the request object. 
     * @param req A SAML request object 
     * @return a SOAPMessage 
     * @exception SAMLException
     */
    private static String createSOAPMessage(Request req)
                               throws SAMLException {
        if (req == null){
            throw new SAMLException(SAMLUtils.bundle.getString("nullInput"));
        }

        try {
            StringBuffer envBegin = new StringBuffer(100);
            envBegin.append("<").append(SAMLConstants.SOAP_ENV_PREFIX).
                append(":Envelope").append(SAMLConstants.SPACE).
                append("xmlns:").append(SAMLConstants.SOAP_ENV_PREFIX).
                append("=\"").append(SAMLConstants.SOAP_URI).append("\">").
                append(SAMLConstants.NL).append("<").
                append(SAMLConstants.SOAP_ENV_PREFIX).append(":Body>").
                append(SAMLConstants.NL);

            StringBuffer envEnd = new StringBuffer(100);
            envEnd.append(SAMLConstants.START_END_ELEMENT).
                append(SAMLConstants.SOAP_ENV_PREFIX).append(":Body>").
                append(SAMLConstants.NL).
                append(SAMLConstants.START_END_ELEMENT).
                append(SAMLConstants.SOAP_ENV_PREFIX).
                append(":Envelope>").append(SAMLConstants.NL);

            StringBuffer sb = new StringBuffer(300);
            sb.append(envBegin).append(req.toString(true, true)).append(envEnd);
            return(sb.toString());
        } catch (Exception e) {
            throw new SAMLException(e.getMessage()); 
        }   
    }
    
    /**
     * This private method is designed to get the URLEndpoint which points to 
     * the partner's SOAP Receiver service, such as the URLEndpoint of 
     * SAMLSOAPReceiver servlet in OpenAM context.
     * @param destSite  A object of 
     *                com.sun.identity.saml.common.SAMLServiceManager.SOAPEntry
     * @param to An URLEndpoint object 
     * @exception IOException if URL is invalid
     * @exception SAMLException if SAML error occurs during the process
     */
    private static String createSOAPReceiverUrl(
            com.sun.identity.saml.common.SAMLServiceManager.SOAPEntry destSite, 
            String to) throws IOException, SAMLException {
        if (destSite == null || to == null || to.length() == 0) {
            throw new SAMLException(SAMLUtils.bundle.getString("nullInput"));
        }
        //get authentication type 
        String authtype = destSite.getAuthType();    
        String urlEndpoint  = null;
        int idnx = -1; 
        if ((idnx = to.indexOf("//")) == -1) {
            SAMLUtils.debug.error("SAMLClient:createSOAPReceiverUrl:" +
                                  "Illegal format of input parameter.");  
            throw new SAMLException(
                      SAMLUtils.bundle.getString("illegalFormatSOAPUrl")); 
        }
        String protocol = to.substring(0, idnx-1);  
        // check if the authentication type matches the protocol specified in 
        // input parameter "to". 
        if (authtype.equalsIgnoreCase(SAMLConstants.BASICAUTH) || 
            authtype.equalsIgnoreCase(SAMLConstants.NOAUTH)) {
            if (!protocol.equals(SAMLConstants.HTTP)) {    
                if (SystemConfigurationUtil.isServerMode()) {
                    String[] data = {SAMLUtils.bundle.getString(
                      "mismatchAuthTypeandProtocol")};
                    LogUtils.error(java.util.logging.Level.INFO,
                        LogUtils.AUTH_PROTOCOL_MISMATCH, data);
                }
                throw new SAMLException(    
                    SAMLUtils.bundle.getString("mismatchAuthTypeandProtocol"));
            }
        } else if (authtype.equalsIgnoreCase(SAMLConstants.SSLWITHBASICAUTH)  
                || authtype.equalsIgnoreCase(SAMLConstants.SSL)) {
            if (!protocol.equals(SAMLConstants.HTTPS)) {    
                if (SystemConfigurationUtil.isServerMode()) {
                    String[] data = {SAMLUtils.bundle.getString(
                      "mismatchAuthTypeandProtocol")};
                    LogUtils.error(java.util.logging.Level.INFO,
                        LogUtils.AUTH_PROTOCOL_MISMATCH, data);
                }
                throw new SAMLException(
                  SAMLUtils.bundle.getString("mismatchAuthTypeandProtocol"));
            }
        } else {
            if (SystemConfigurationUtil.isServerMode()) {
                String[] data = {SAMLUtils.bundle.getString(
                   "wrongAuthType")};
                LogUtils.error(java.util.logging.Level.INFO,
                    LogUtils.INVALID_AUTH_TYPE, data);
            }
            throw new SAMLException(
                      SAMLUtils.bundle.getString("wrongAuthType"));
        }

        // If the authentication type is BASICAUTH or SSLWITHBASICAUTH, 
        // call ServiceManager to retrieve the partner's user name and password 
        // which protects the partner's SOAPReceiverURL. 
        if (authtype.equalsIgnoreCase(SAMLConstants.BASICAUTH) || 
            authtype.equalsIgnoreCase(SAMLConstants.SSLWITHBASICAUTH)) {
            String username = destSite.getBasicAuthUserID();
            String password = destSite.getBasicAuthPassword();
            if (username == null || password == null) {
                SAMLUtils.debug.error("SAMLClient:createSOAPReceiverUrl:" +
                    "PartnerSite required basic authentication. But the " +
                    "user name or password used for authentication is null.");
                throw new SAMLException(
                    SAMLUtils.bundle.getString("wrongConfigBasicAuth"));
            }
            String toSOAP = to.substring(0, idnx+2) + username + ":" +
                            password + "@" + to.substring(idnx+2); 
            urlEndpoint = toSOAP;
        } else {
            urlEndpoint = to; 
        }
        if (SAMLUtils.debug.messageEnabled()) {
            SAMLUtils.debug.message("Sending message to URL: " +
                                    urlEndpoint);
        }
        if (SystemConfigurationUtil.isServerMode()) {
            String[] data = {SAMLUtils.bundle.getString("SOAPReceiverURL"),
                urlEndpoint};
            LogUtils.access(java.util.logging.Level.FINE, 
                LogUtils.SOAP_RECEIVER_URL, data);
        }
        return urlEndpoint;
    }
    
    /**
     * This private method is designed to get the SAML response object from  
     * a SOAPMessage string. 
     * @param xmlString A String representing a string of SOAPMessage 
     * @return a SAML Response object
     * @exception IOException if an input or output exception occurs when
     *     connecting to SAML service URL
     * @exception SAMLException if SAML error occurs during the process
     */
    private static Response getSAMLResponse(String xmlString) 
                            throws IOException, SAMLException {
        if (xmlString == null || xmlString.length() == 0) {
            throw new SAMLException(SAMLUtils.bundle.getString("nullInput"));
        }   
        Response samlResp = null;                                
        Document doc = XMLUtils.toDOMDocument(xmlString, SAMLUtils.debug);
        Element root= doc.getDocumentElement();
        String rootName  = root.getLocalName();
        if ((rootName == null) || (rootName.length() == 0)) {
            SAMLUtils.debug.error("Missing Envelope tag.");
            throw new SAMLException (
                      SAMLUtils.bundle.getString("missingSOAPEnvTag"));
        }
        if (!(rootName.equals("Envelope")) ||
            (!(root.getNamespaceURI().equals(SAMLConstants.SOAP_URI)))) {
            SAMLUtils.debug.error("Wrong Envelope tag or namespace.");   
            throw new SAMLException(
                SAMLUtils.bundle.getString("serverError"));
        }
        //exam the child element of 
        NodeList  nodes = root.getChildNodes();
        int nodeCount = nodes.getLength();
        if (nodeCount <= 0) {
            SAMLUtils.debug.error("Envelope does not contain a SOAP body."); 
            throw new SAMLException(
                      SAMLUtils.bundle.getString("missingSOAPBody"));
        }
        String tagName = null; 
        String ctagName = null; 
        Node currentNode = null; 
        Node cnode = null; 
        for (int i = 0; i < nodeCount; i++) {
            currentNode = nodes.item(i);
            if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
                tagName = currentNode.getLocalName();
                if ((tagName == null) || tagName.length() == 0) {
                    SAMLUtils.debug.error("Missing tag name of child element");
                    throw new SAMLException(
                             SAMLUtils.bundle.getString("missingChildTagName"));
                }
                if (tagName.equals("Body")) {
                    NodeList cNodes = currentNode.getChildNodes(); 
                    int cnodeCount = cNodes.getLength(); 
                    for (int j = 0; j < cnodeCount; j++) {
                        cnode = cNodes.item(j); 
                        if (cnode.getNodeType() == Node.ELEMENT_NODE){ 
                            ctagName = cnode.getLocalName();
                            if ((ctagName == null) || ctagName.length() == 0) {
                                SAMLUtils.debug.error("Missing tag name of " +
                                            "child element of ");
                                throw new SAMLException(      
                                          SAMLUtils.bundle.getString(
                                                    "missingChildTagName"));
                            }
                            if (ctagName.equals("Fault")) {
                                SAMLUtils.debug.error("SOAPFault error."); 
                                throw new SAMLException(
                                          XMLUtils.print(cnode)); 
                            } else if (ctagName.equals("Response")) {
                                samlResp = new Response((Element) cnode); 
                                if (SAMLUtils.debug.messageEnabled()) {
                                    SAMLUtils.debug.message("SAML Response:" +
                                                        samlResp.toString());
                                }
                                break;
                            } else {
                                SAMLUtils.debug.error("Wrong child element " +
                                                      "in SOAPBody");
                                throw new SAMLException(
                                          SAMLUtils.bundle.getString(
                                          "wrongSOAPBody")); 
                            }
                        }
                    } // end of for(int j=0; j AssertionArtifact(s). 
     *
     * @param arti An array of String 
     * @return a List object representing a list of Assertions
     * @exception IOException if an input or output exception occurs when
     *     connecting to SAML service URL
     * @exception SAMLException if SAML error occurs during the process
     */
    public static List artifactQueryHandler(String[] arti, String connecto) 
                       throws IOException, SAMLException {
        if ((arti == null) || (arti.length == 0)) {
            SAMLUtils.debug.message("artifactQueryHandler: null input.");
            throw new SAMLException(SAMLUtils.bundle.getString("nullInput"));
        }

        String firstSourceID = null;
        com.sun.identity.saml.common.SAMLServiceManager.SOAPEntry dest= null;
        Response samlresponse = null; 
        List al = new ArrayList(); 
        List artl = new ArrayList();
        
        AssertionArtifact firstArtifact = new AssertionArtifact(arti[0]); 
        firstSourceID = firstArtifact.getSourceID();
        if (SystemConfigurationUtil.isServerMode()) {
            String[] data = {SAMLUtils.bundle.getString("Artifact") + " " + 0, 
                arti[0]};
            LogUtils.access(java.util.logging.Level.INFO,
                LogUtils.ARTIFACT_TO_SEND, data);
        }
        artl.add(firstArtifact);
        al.add(arti[0]);
        AssertionArtifact assertArtifact = null; 
        String destination = null; 
        for (int k = 1; k < arti.length; k++) {
            // check if all Artifact come from the same source id             
            assertArtifact = new AssertionArtifact(arti[k]);
            destination = assertArtifact.getSourceID(); 
            if (SAMLUtils.debug.messageEnabled()) {
                SAMLUtils.debug.message("SourceID within the Artifact is " +
                                        destination);
            }
            if (!destination.equals(firstSourceID)) {
                if (SAMLUtils.debug.messageEnabled()) {
                    SAMLUtils.debug.message("Received multiple Artifacts " +
                                                "have different source id.");
                }
                throw new SAMLException(
                          SAMLUtils.bundle.getString("sourceidDifferent")); 
            }
            if (SystemConfigurationUtil.isServerMode()) {
                String[] data = {SAMLUtils.bundle.getString("Artifact") + " " 
                    + k, arti[k]};
                LogUtils.access(java.util.logging.Level.FINE,
                    LogUtils.ARTIFACT_TO_SEND, data);
            }
            artl.add(assertArtifact);
            al.add(arti[k]);
        }
        
        try {
            //Retrieve the soap-receiver-url using the sourceid inside of 
            //the AssertionArtifact 
            String to = null; 
            Map soaps = (Map) SAMLServiceManager.getAttribute(
                                                   SAMLConstants.PARTNER_URLS); 
            if (soaps == null) {
                SAMLUtils.debug.error(
                                  SAMLUtils.bundle.getString("nullPartnerUrl"));
                throw new SAMLException(
                                  SAMLUtils.bundle.getString("nullPartnerUrl"));
            }
            String urlEndpoint = null; 
            if (soaps.containsKey(firstSourceID)) {
                dest = (SAMLServiceManager.SOAPEntry) soaps.get(firstSourceID);
                to = dest.getSOAPUrl(); 
                if (to==null) {
                    if (connecto == null || connecto.length() == 0) {
                        if (SystemConfigurationUtil.isServerMode()) {
                            String[] data = {SAMLUtils.bundle.getString(
                                "wrongPartnerSOAPUrl")};
                            LogUtils.error(java.util.logging.Level.INFO,
                                LogUtils.WRONG_SOAP_URL, data);
                        }
                        throw new SAMLException(
                          SAMLUtils.bundle.getString("wrongPartnerSOAPUrl")); 
                    } else {
                        urlEndpoint = connecto;
                    }
                } else {
                    urlEndpoint = createSOAPReceiverUrl(dest, to); 
                }
            } else {
                if (SAMLUtils.debug.messageEnabled()) {
                    SAMLUtils.debug.message("SAMLClient:artifactQueryHandler: " 
                                 + "Failed to locate SOAP-Receiver-URL " +
                                 "using the source id from AssertionArtifact.");
                }
                if (connecto == null || connecto.length() == 0) {
                    throw new SAMLException(
                             SAMLUtils.bundle.getString("failedLocateSOAPUrl"));
                } else { 
                    urlEndpoint = connecto; 
                }
            }   
         
            if (urlEndpoint == null) {
                SAMLUtils.debug.error("SAMLClient:artifactQueryHandler:" + 
                                      "createSOAPReceiverURL Error!");
                if (SystemConfigurationUtil.isServerMode()) {
                    String[] data = {SAMLUtils.bundle.getString(
                        "wrongPartnerSOAPUrl")};
                    LogUtils.error(java.util.logging.Level.INFO,
                        LogUtils.WRONG_SOAP_URL, data);
                }
                throw new SAMLException(SAMLUtils.bundle.getString(
                                        "wrongPartnerSOAPUrl")); 
            }
            //generate SAML Request    
            Request req = new Request(null, artl);
            String ver = dest.getVersion(); 
            if (ver != null) {
                StringTokenizer st = new StringTokenizer(ver,".");
                if (st.countTokens() == 2) {
                    req.setMajorVersion(
                        Integer.parseInt(st.nextToken().trim()));
                    req.setMinorVersion(
                        Integer.parseInt(st.nextToken().trim()));
                }
            }

            if (((Boolean) SAMLServiceManager.getAttribute(
                SAMLConstants.SIGN_REQUEST)).booleanValue())
            {
                req.signXML();
            }
            // SOAPMessage msg = createSOAPMessage(req);  
            String xmlString = createSOAPMessage(req);

            // Send the message to the provider using the connection.
            if (SAMLUtils.debug.messageEnabled()) {
                SAMLUtils.debug.message("SENDING message: \n " + xmlString);  
            }
            if (SystemConfigurationUtil.isServerMode()) {
                String[] data = {SAMLUtils.bundle.getString(
                    "sendingSAMLRequest"), xmlString};
                LogUtils.access(java.util.logging.Level.FINE, 
                    LogUtils.SAML_ARTIFACT_QUERY, data); 
            }
            
            // SOAPMessage  reply = con.call(msg, urlEndpoint); 
            String[] urls = { urlEndpoint };
            SOAPClient client = new SOAPClient(urls);
            InputStream inbuf = client.call(xmlString, null, null);
            StringBuffer reply = new StringBuffer();
            String line;
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                inbuf, "UTF-8"));
            while ((line = reader.readLine()) != null) {
                reply.append(line).append("\n");
            }

            //reply should contain SAML response 
            if (reply == null) {
                if (SystemConfigurationUtil.isServerMode()) {
                    String[] data = {SAMLUtils.bundle.getString(
                        "noReplyfromSOAPReceiver")};
                    LogUtils.error(java.util.logging.Level.INFO, 
                        LogUtils.NO_REPLY_FROM_SOAP_RECEIVER, data);
                }
                throw new SAMLException( 
                         SAMLUtils.bundle.getString("noReplyfromSOAPReceiver"));
            }
            
            // check the SOAP message for any SOAP related errors
            // before passing control to SAML processor
            xmlString = reply.toString();
            if (SAMLUtils.debug.messageEnabled()) {
                SAMLUtils.debug.message("REPLIED message: \n " + xmlString);  
            }
            if (SystemConfigurationUtil.isServerMode()) {
                String[] data = {SAMLUtils.bundle.getString(
                    "repliedSOAPMessage"), xmlString};
                LogUtils.access(java.util.logging.Level.FINE, 
                    LogUtils.REPLIED_SOAP_MESSAGE, data);
            }
            samlresponse = getSAMLResponse(xmlString); 
            if (samlresponse == null) {
                SAMLUtils.debug.error("SAMLClient:artifactQueryHandler:"+
                            "No SAML Response contained in SOAPMessage.");
                if (SystemConfigurationUtil.isServerMode()) {
                    String[] data = {SAMLUtils.bundle.getString(
                        "noSAMLResponse")};
                    LogUtils.error(java.util.logging.Level.INFO, 
                        LogUtils.NULL_SAML_RESPONSE, data);
                }
                throw new SAMLException(SAMLUtils.bundle.getString(
                                        "noSAMLResponse"));
            }
        } catch (Exception e) {
            SAMLUtils.debug.error("SAMLClient:artifactQueryHandler", e); 
            throw new SAMLException(e.getMessage()); 
        }
        if (SAMLUtils.debug.messageEnabled()) {
            SAMLUtils.debug.message("Start to process SAML Response..."); 
        }
        // Process saml Response 
        if (!samlresponse.isSignatureValid()) {
            if (SystemConfigurationUtil.isServerMode()) {
                String[] data = {SAMLUtils.bundle.getString(
                   "cannotVerifyResponse")};
                LogUtils.error(java.util.logging.Level.INFO, 
                   LogUtils.INVALID_RESPONSE_SIGNATURE, data);
            }
            throw new SAMLException(
                      SAMLUtils.bundle.getString("cannotVerifyResponse"));
        }       
        try {        
            String statuscode= samlresponse.getStatus().getStatusCode().
                               getValue(); 
            int idex=0; 
            if ((idex=statuscode.indexOf(":")) == -1) {
                throw new SAMLException(
                      SAMLUtils.bundle.getString("wrongformatStatusCode")); 
            }
            if (!(statuscode.substring(idex).equals(":Success"))) {
               SAMLUtils.debug.error("Error:SAML StatusCode is not Success");
               throw new SAMLException(
                   SAMLUtils.displayXML(samlresponse.getStatus().toString())); 
            }      
        } catch (Exception e) {
            if (SystemConfigurationUtil.isServerMode()) {
                String[] data = {SAMLUtils.bundle.getString(
                    "errorSAMLStatusCode")};
                LogUtils.error(java.util.logging.Level.INFO, 
                    LogUtils.ERROR_RESPONSE_STATUS, data);
            }
            throw new SAMLException(e.getMessage());
        } 
        // retrieve SAML Assertion
        List asserts = new ArrayList(); 
        asserts = getAssertionList(samlresponse, al); 
        return asserts; 
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy