This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, visit https://wso2.com/documentation/.

Processing SAML Response

WSO2 App Manager can be configured to send the whole SAML response generated by the identity provider, to the backend web application. For more information, see Sending SAML response to backend. Once the required configurations are done, the base 64 encoded SAML response is sent to the backend application as a HTTP transport header called AppMgtSAML2Response.

When the web application receives the HTTP request, it reads the request and the encoded SAML response, which has been sent as an HTTP header value. When this particular header value is extracted from the request, it can be processed to get the actual SAML response generated from the identity provider.

The encoded SAML response can be processed with the use of different libraries. Java OpenSAML 2.2.3 library has been used in the following example to process the SAML Response received at the backend. The steps for processing the SAML response are illustrated below.

  1. Extract the encoded SAML response from the HTTP servlet request.

    String samlResponseHeader = request.getHeader("AppMgtSAML2Response");
  2. Decode the extracted header value using the Base64 library.

    byte[] base64DecodedResponse = Base64.decode(samlResponseHeader);
  3. Once the header value is decoded, the decoded SAML response has to be unmarshalled. In order to do that, convert the decoded response into an input byte stream and create the DOM element object out of the response string.

    ByteArrayInputStream inputStreams = new ByteArrayInputStream(base64DecodedResponse);
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
    
    Document document = docBuilder.parse(inputStreams);
    Element element = document.getDocumentElement();
  4. Unmarshall the DOM element.

    UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
    Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
    XMLObject responseXmlObj = unmarshaller.unmarshall(element);
  5. Ultimately, the XML object is casted into the SAML 2.0 response message.

    Response response = (Response) responseXmlObj;
  6. The processing of the SAML response message is completed and the response is ready. The completed implementation of the SAML token processing sample is shown below:

    import org.opensaml.Configuration;
    import org.opensaml.DefaultBootstrap;
    import org.opensaml.common.SAMLException;
    import org.opensaml.saml2.core.Response;
    import org.opensaml.xml.ConfigurationException;
    import org.opensaml.xml.XMLObject;
    import org.opensaml.xml.io.Unmarshaller;
    import org.opensaml.xml.io.UnmarshallerFactory;
    import org.opensaml.xml.io.UnmarshallingException;
    import org.opensaml.xml.util.Base64;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    import java.io.ByteArrayInputStream;
    
    
    public class SAMLResponseManager {
        
        private static boolean bootStrapped = false;
        public static final String APPM_MGT_SAML2_RESPONSE = "AppMgtSAML2Response";
    
        public Response processSAMLResponse(HttpServletRequest request) throws Exception {
    
            //Reading AppMgtSAML2Response header value from the request
            String samlResponseHeader = request.getHeader(APPM_MGT_SAML2_RESPONSE);
    
            //Decoding the extracted encoded SAML Response
            byte[] base64DecodedResponse = Base64.decode(samlResponseHeader);
            Response response = null;
    
            //Initializing Open SAML Library
            doBootstrap();
    
            try {
                //Converting the decoded SAML Response string into DOM object
                ByteArrayInputStream inputStreams = new ByteArrayInputStream(base64DecodedResponse);
                DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                documentBuilderFactory.setNamespaceAware(true);
                DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
                Document document = docBuilder.parse(inputStreams);
                Element element = document.getDocumentElement();
    
                //Unmarshalling the element
                UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
                Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
                XMLObject responseXmlObj = unmarshaller.unmarshall(element);
                response = (Response) responseXmlObj;
    
            } catch (ParserConfigurationException e) {
                throw new SAMLException("Error while parsing the decoded SAML Response", e);
            } catch (UnmarshallingException e) {
                throw new SAMLException("Error while unmarshalling the decoded SAML Response", e);
            }
            return response;
    
        }
        public static void doBootstrap() throws SAMLException {
          /* Initializing the OpenSAML library */
            if (!bootStrapped) {
                try {
                    DefaultBootstrap.bootstrap();
                    bootStrapped = true;
                } catch (ConfigurationException e) {
                    throw new SAMLException("Error while bootstrapping OpenSAML library", e);
                }
            }
        }
    
    }