public SAMLAuthenticationSession processResponse(String url, String relayState,
            String encodedResponse) throws GuacamoleException {

        if (relayState == null)
            throw new GuacamoleSecurityException("\"RelayState\" value "
                    + "is missing from SAML response.");

        SAMLAuthenticationSession session = sessionManager.resume(relayState);
        if (session == null)
            throw new GuacamoleSecurityException("\"RelayState\" value "
                    + "included with SAML response is not valid.");

        try {

            // Decode received SAML response
            SamlResponse response = new SamlResponse(confService.getSamlSettings(),
                    url, encodedResponse);

            // Validate SAML response timestamp, signature, etc.
            if (!response.isValid(session.getRequestID())) {
                Exception validationException = response.getValidationException();
                throw new GuacamoleSecurityException("SAML response did not "
                        + "pass validation: " + validationException.getMessage(),
                        validationException);
            }

            // Parse identity asserted by SAML IdP
            session.setIdentity(new AssertedIdentity(response));
            return session;

        }
        catch (ValidationError e) {
            throw new GuacamoleSecurityException("SAML response did not pass "
                    + "validation: " + e.getMessage(), e);
        }
        catch (SettingsException e) {
            throw new GuacamoleServerException("Current SAML settings are "
                    + "insufficient to decrypt/parse the received SAML "
                    + "response.", e);
        }
        catch (ParserConfigurationException | SAXException | XPathExpressionException e) {
            throw new GuacamoleServerException("XML contents of SAML "
                    + "response could not be parsed.", e);
        }
        catch (IOException e) {
            throw new GuacamoleServerException("Contents of SAML response "
                    + "could not be decrypted/read.", e);
        }

    }
Processes the given SAML response, as received by the SAML ACS endpoint
at the given URL, producing an {@link SAMLAuthenticationSession} that now
includes a valid assertion of the user's identity. If the SAML response
is invalid in any way, an exception is thrown.

@param url
    The URL of the ACS endpoint that received the SAML response. This
    should be the URL pointing to the single POST-handling endpoint of
    {@link AssertionConsumerServiceResource}.

@param relayState
    The "RelayState" value originally provided in the SAML request,
    which in our case is the transient the session identifier of the
    in-progress authentication attempt. The SAML standard requires that
    the identity provider include the "RelayState" value it received
    alongside its SAML response.

@param encodedResponse
    The response received from the SAML IdP via the ACS endpoint at the
    given URL.

@return
    The {@link SAMLAuthenticationSession} associated with the in-progress
    authentication attempt, now associated with the {@link AssertedIdentity}
    representing the identity of the user asserted by the SAML IdP.

@throws GuacamoleException
    If the given SAML response is not valid, or if the configuration
    information required to validate or decrypt the response cannot be
    read.
extensions/guacamole-auth-sso/modules/guacamole-auth-sso-saml/src/main/java/org/apache/guacamole/auth/saml/acs/SAMLService.java