Class OpenSaml4AuthenticationProvider

  • All Implemented Interfaces:
    org.springframework.security.authentication.AuthenticationProvider

    public final class OpenSaml4AuthenticationProvider
    extends java.lang.Object
    implements org.springframework.security.authentication.AuthenticationProvider
    Implementation of AuthenticationProvider for SAML authentications when receiving a Response object containing an Assertion. This implementation uses the OpenSAML 4 library.

    The OpenSaml4AuthenticationProvider supports Saml2AuthenticationToken objects that contain a SAML response in its decoded XML format Saml2AuthenticationToken.getSaml2Response() along with the information about the asserting party, the identity provider (IDP), as well as the relying party, the service provider (SP, this application).

    The Saml2AuthenticationToken will be processed into a SAML Response object. The SAML response object can be signed. If the Response is signed, a signature will not be required on the assertion.

    While a response object can contain a list of assertion, this provider will only leverage the first valid assertion for the purpose of authentication. Assertions that do not pass validation will be ignored. If no valid assertions are found a Saml2AuthenticationException is thrown.

    This provider supports two types of encrypted SAML elements

    If the assertion is encrypted, then signature validation on the assertion is no longer required.

    This provider does not perform an X509 certificate validation on the configured asserting party, IDP, verification certificates.

    Since:
    5.5
    See Also:
    SAML 2 StatusResponse, OpenSAML 3
    • Method Detail

      • setResponseElementsDecrypter

        public void setResponseElementsDecrypter​(java.util.function.Consumer<OpenSaml4AuthenticationProvider.ResponseToken> responseElementsDecrypter)
        Set the Consumer strategy to use for decrypting elements of a validated Response. The default strategy decrypts all EncryptedAssertions using OpenSAML's Decrypter, adding the results to Response.getAssertions(). You can use this method to configure the Decrypter instance like so:
                OpenSamlAuthenticationProvider provider = new OpenSamlAuthenticationProvider();
                provider.setResponseElementsDecrypter((responseToken) -> {
                    DecrypterParameters parameters = new DecrypterParameters();
                    // ... set parameters as needed
                    Decrypter decrypter = new Decrypter(parameters);
                        Response response = responseToken.getResponse();
                EncryptedAssertion encrypted = response.getEncryptedAssertions().get(0);
                try {
                        Assertion assertion = decrypter.decrypt(encrypted);
                        response.getAssertions().add(assertion);
                } catch (Exception e) {
                        throw new Saml2AuthenticationException(...);
                }
                });
         
        Or, in the event that you have your own custom decryption interface, the same pattern applies:
                OpenSamlAuthenticationProvider provider = new OpenSamlAuthenticationProvider();
                Converter<EncryptedAssertion, Assertion> myService = ...
                provider.setResponseDecrypter((responseToken) -> {
                   Response response = responseToken.getResponse();
                   response.getEncryptedAssertions().stream()
                                .map(service::decrypt).forEach(response.getAssertions()::add);
                });
         
        This is valuable when using an external service to perform the decryption.
        Parameters:
        responseElementsDecrypter - the Consumer for decrypting response elements
        Since:
        5.5
      • setResponseValidator

        public void setResponseValidator​(org.springframework.core.convert.converter.Converter<OpenSaml4AuthenticationProvider.ResponseToken,​Saml2ResponseValidatorResult> responseValidator)
        Set the Converter to use for validating the SAML 2.0 Response. You can still invoke the default validator by delegating to createDefaultResponseValidator(), like so:
         OpenSaml4AuthenticationProvider provider = new OpenSaml4AuthenticationProvider();
         provider.setResponseValidator(responseToken -> {
                        Saml2ResponseValidatorResult result = createDefaultResponseValidator()
                                .convert(responseToken)
                        return result.concat(myCustomValidator.convert(responseToken));
         });
         
        Parameters:
        responseValidator - the Converter to use
        Since:
        5.6
      • setAssertionElementsDecrypter

        public void setAssertionElementsDecrypter​(java.util.function.Consumer<OpenSaml4AuthenticationProvider.AssertionToken> assertionDecrypter)
        Set the Consumer strategy to use for decrypting elements of a validated Assertion. You can use this method to configure the Decrypter used like so:
                OpenSamlAuthenticationProvider provider = new OpenSamlAuthenticationProvider();
                provider.setResponseDecrypter((assertionToken) -> {
                    DecrypterParameters parameters = new DecrypterParameters();
                    // ... set parameters as needed
                    Decrypter decrypter = new Decrypter(parameters);
                        Assertion assertion = assertionToken.getAssertion();
                EncryptedID encrypted = assertion.getSubject().getEncryptedID();
                try {
                        NameID name = decrypter.decrypt(encrypted);
                        assertion.getSubject().setNameID(name);
                } catch (Exception e) {
                        throw new Saml2AuthenticationException(...);
                }
                });
         
        Or, in the event that you have your own custom interface, the same pattern applies:
                OpenSamlAuthenticationProvider provider = new OpenSamlAuthenticationProvider();
                MyDecryptionService myService = ...
                provider.setResponseDecrypter((responseToken) -> {
                        Assertion assertion = assertionToken.getAssertion();
                        EncryptedID encrypted = assertion.getSubject().getEncryptedID();
                        NameID name = myService.decrypt(encrypted);
                        assertion.getSubject().setNameID(name);
                });
         
        Parameters:
        assertionDecrypter - the Consumer for decrypting assertion elements
        Since:
        5.5
      • setResponseAuthenticationConverter

        public void setResponseAuthenticationConverter​(org.springframework.core.convert.converter.Converter<OpenSaml4AuthenticationProvider.ResponseToken,​? extends org.springframework.security.authentication.AbstractAuthenticationToken> responseAuthenticationConverter)
        Set the Converter to use for converting a validated Response into an AbstractAuthenticationToken. You can delegate to the default behavior by calling createDefaultResponseAuthenticationConverter() like so:
                OpenSamlAuthenticationProvider provider = new OpenSamlAuthenticationProvider();
                Converter<ResponseToken, Saml2Authentication> authenticationConverter =
                                createDefaultResponseAuthenticationConverter();
                provider.setResponseAuthenticationConverter(responseToken -> {
                        Saml2Authentication authentication = authenticationConverter.convert(responseToken);
                        User user = myUserRepository.findByUsername(authentication.getName());
                        return new MyAuthentication(authentication, user);
                });
         
        Parameters:
        responseAuthenticationConverter - the Converter to use
        Since:
        5.4
      • createDefaultAssertionValidator

        public static org.springframework.core.convert.converter.Converter<OpenSaml4AuthenticationProvider.AssertionToken,​Saml2ResponseValidatorResult> createDefaultAssertionValidator()
        Construct a default strategy for validating each SAML 2.0 Assertion and associated Authentication token
        Returns:
        the default assertion validator strategy
      • createDefaultAssertionValidator

        public static org.springframework.core.convert.converter.Converter<OpenSaml4AuthenticationProvider.AssertionToken,​Saml2ResponseValidatorResult> createDefaultAssertionValidator​(org.springframework.core.convert.converter.Converter<OpenSaml4AuthenticationProvider.AssertionToken,​org.opensaml.saml.common.assertion.ValidationContext> contextConverter)
        Construct a default strategy for validating each SAML 2.0 Assertion and associated Authentication token
        Parameters:
        contextConverter - the conversion strategy to use to generate a ValidationContext for each assertion being validated
        Returns:
        the default assertion validator strategy
      • authenticate

        public org.springframework.security.core.Authentication authenticate​(org.springframework.security.core.Authentication authentication)
                                                                      throws org.springframework.security.core.AuthenticationException
        Specified by:
        authenticate in interface org.springframework.security.authentication.AuthenticationProvider
        Parameters:
        authentication - the authentication request object, must be of type Saml2AuthenticationToken
        Returns:
        Saml2Authentication if the assertion is valid
        Throws:
        org.springframework.security.core.AuthenticationException - if a validation exception occurs
      • supports

        public boolean supports​(java.lang.Class<?> authentication)
        Specified by:
        supports in interface org.springframework.security.authentication.AuthenticationProvider