Class OpenSaml4AuthenticationProvider

java.lang.Object
org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider
All Implemented Interfaces:
AuthenticationProvider

public final class OpenSaml4AuthenticationProvider extends Object implements 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:
  • Constructor Details

  • Method Details

    • setResponseElementsDecrypter

      public void setResponseElementsDecrypter(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
    • setAssertionValidator

      public void setAssertionValidator(org.springframework.core.convert.converter.Converter<OpenSaml4AuthenticationProvider.AssertionToken,Saml2ResponseValidatorResult> assertionValidator)
      Set the Converter to use for validating each Assertion in the SAML 2.0 Response. You can still invoke the default validator by delgating to createAssertionValidator(java.lang.String, org.springframework.core.convert.converter.Converter<org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.AssertionToken, org.opensaml.saml.saml2.assertion.SAML20AssertionValidator>, org.springframework.core.convert.converter.Converter<org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.AssertionToken, org.opensaml.saml.common.assertion.ValidationContext>), like so:
              OpenSamlAuthenticationProvider provider = new OpenSamlAuthenticationProvider();
        provider.setAssertionValidator(assertionToken -> {
                      Saml2ResponseValidatorResult result = createDefaultAssertionValidator()
                              .convert(assertionToken)
                      return result.concat(myCustomValidator.convert(assertionToken));
        });
       
      You can also use this method to configure the provider to use a different ValidationContext from the default, like so:
              OpenSamlAuthenticationProvider provider = new OpenSamlAuthenticationProvider();
              provider.setAssertionValidator(
                      createDefaultAssertionValidator(assertionToken -> {
                              Map<String, Object> params = new HashMap<>();
                              params.put(CLOCK_SKEW, 2 * 60 * 1000);
                              // other parameters
                              return new ValidationContext(params);
                      }));
       
      Consider taking a look at createValidationContext(org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.AssertionToken, java.util.function.Consumer<java.util.Map<java.lang.String, java.lang.Object>>) to see how it constructs a ValidationContext. It is not necessary to delegate to the default validator. You can safely replace it entirely with your own. Note that signature verification is performed as a separate step from this validator.
      Parameters:
      assertionValidator - the validator to use
      Since:
      5.4
    • setAssertionElementsDecrypter

      public void setAssertionElementsDecrypter(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 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
    • createDefaultResponseValidator

      public static org.springframework.core.convert.converter.Converter<OpenSaml4AuthenticationProvider.ResponseToken,Saml2ResponseValidatorResult> createDefaultResponseValidator()
      Construct a default strategy for validating the SAML 2.0 Response
      Returns:
      the default response validator strategy
      Since:
      5.6
    • 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

      @Deprecated 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
    • createDefaultAssertionValidatorWithParameters

      public static org.springframework.core.convert.converter.Converter<OpenSaml4AuthenticationProvider.AssertionToken,Saml2ResponseValidatorResult> createDefaultAssertionValidatorWithParameters(Consumer<Map<String,Object>> validationContextParameters)
      Construct a default strategy for validating each SAML 2.0 Assertion and associated Authentication token
      Parameters:
      validationContextParameters - a consumer for editing the values passed to the ValidationContext for each assertion being validated
      Returns:
      the default assertion validator strategy
      Since:
      5.8
    • createDefaultResponseAuthenticationConverter

      public static org.springframework.core.convert.converter.Converter<OpenSaml4AuthenticationProvider.ResponseToken,Saml2Authentication> createDefaultResponseAuthenticationConverter()
      Construct a default strategy for converting a SAML 2.0 Response and Authentication token into a Saml2Authentication
      Returns:
      the default response authentication converter strategy
    • authenticate

      public Authentication authenticate(Authentication authentication) throws AuthenticationException
      Description copied from interface: AuthenticationProvider
      Performs authentication with the same contract as AuthenticationManager.authenticate(Authentication) .
      Specified by:
      authenticate in interface AuthenticationProvider
      Parameters:
      authentication - the authentication request object, must be of type Saml2AuthenticationToken
      Returns:
      Saml2Authentication if the assertion is valid
      Throws:
      AuthenticationException - if a validation exception occurs
    • supports

      public boolean supports(Class<?> authentication)
      Description copied from interface: AuthenticationProvider
      Returns true if this AuthenticationProvider supports the indicated Authentication object.

      Returning true does not guarantee an AuthenticationProvider will be able to authenticate the presented instance of the Authentication class. It simply indicates it can support closer evaluation of it. An AuthenticationProvider can still return null from the AuthenticationProvider.authenticate(Authentication) method to indicate another AuthenticationProvider should be tried.

      Selection of an AuthenticationProvider capable of performing authentication is conducted at runtime the ProviderManager.

      Specified by:
      supports in interface AuthenticationProvider
      Returns:
      true if the implementation can more closely evaluate the Authentication class presented