Describe the bug * In version 5.x

OpenSaml4AuthenticationProvider.process 1. this.responseValidator.convert(responseToken)); 1. then check assertion

  • In version 6.1

OpenSaml4AuthenticationProvider.process

  1. check if getEncryptedAssertions exists
  2. this.responseValidator.convert(responseToken));
  3. then check assertion

because of the checking getEncryptedAssertions earlier, this workaround is meaningless. (https://github.com/spring-projects/spring-security/issues/10162)

OpenSaml4AuthenticationProvider authenticationProvider = new OpenSaml4AuthenticationProvider();
Converter<ResponseToken, ResponseToken> decrypt = (responseToken) -> {
    DecryptionParameters parameters = new DecryptionParameters();
    // ... 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(...);
    }
    return response;
};
authenticationProvider.setResponseValidator(decrypt.andThen(createDefaultResponseValidator()));

Expected behavior responseValidator should be executed earlier than checking getEncryptedAssertions exists or alternative solution

A link to a GitHub repository with a minimal, reproducible sample.

Reports that include a sample will take priority over reports that do not. At times, we may require a sample, so it is good to try and include a sample up front.

Comment From: fr2lancer

Hi Any updates on this? Thank you

Comment From: jzheaux

Hi, @fr2lancer, thanks for reaching out.

It sounds like what you want to do is decrypt an unsigned response, which Spring Security does not support.

If I'm understanding you correctly, you can decrypt it yourself like so:

public class MyDecryptingAuthenticationProvider implements AuthenticationProvider {
    private OpenSaml4AuthenticationProvider delegate;

    @Override
    public Authentication authenticate(Authentication authentication) {
        Saml2AuthenticationToken token = (Saml2AuthenticationToken) authentication;
        Response response = extractResponse(authentication);
        performDecryption(response);
        String serialized = serializeResponse(response);
        return new Saml2AuthenticationToken(token.getRelyingPartyRegistration(),
                serialized, token.getAuthenticationRequest());
    }    
}

I'm going to close this as answered, but please feel free to clarify if I've misunderstood.

Comment From: santoshdahal12

I am having same problem. Though the recommended approach seems to be working, but this approach also introduces another problem of parsing xml two times which is expensive operation. Any suggestion or guidance. I have to do this for an app that needs to validate SAML token for many SPs .