Summary

When i modify the AuthnRequest according to the reference (Customize AuthnRequest) i get a perfect working AuthnRequest. Everything works. But when i add a RequestedAuthnContext containing a AuthnContextClassRef the signature value is missing.

Actual Behavior

The signature object is present but the signature value and the digest value is null.

Expected Behavior

The signature object is present , the signature value and the digest value is not null.

### Configuration

  static {
    OpenSamlInitializationService.requireInitialize(factory -> {
      AuthnRequestMarshaller marshaller = new AuthnRequestMarshaller() {
        @Override
        public Element marshall(XMLObject object, Element element) throws MarshallingException {
          configureAuthnRequest((AuthnRequest) object);
          return super.marshall(object, element);
        }

        public Element marshall(XMLObject object, Document document) throws MarshallingException {
          configureAuthnRequest((AuthnRequest) object);
          return super.marshall(object, document);
        }

        private void configureAuthnRequest(AuthnRequest authnRequest) {
          authnRequest.setForceAuthn(true);

          RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder();
          RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder
              .buildObject("urn:oasis:names:tc:SAML:2.0:protocol", "RequestedAuthnContext", "saml2p");
          requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT);
          AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder();
          AuthnContextClassRef ref = authnContextClassRefBuilder.buildObject("urn:oasis:names:tc:SAML:2.0:assertion",
              "AuthnContextClassRef", "saml2");
          ref.setAuthnContextClassRef("SOME-REQUIRED-LEVEL");
          requestedAuthnContext.getAuthnContextClassRefs().add(ref);
          authnRequest.setRequestedAuthnContext(requestedAuthnContext);

        }
      };

      factory.getMarshallerFactory().registerMarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME, marshaller);

    });
  }

Version

5.4.5

Sample

Cant share company code here.

Comment From: jzheaux

Hi, @leneinz, thanks for the report.

You are correct that this approach only works with the AuthnRequest is unsigned. I think it's important to clarify that in the documentation.

Alternatively, you can configure the factory with setAuthenticationRequestContextConverter, which produces an AuthnRequest in the way that you expect.

I'll leave this ticket open for updating the documentation. Can you confirm that doing:

@Bean 
public Saml2AuthenticationRequestFactory authenticationRequestFactory() {
    OpenSamlAuthenticationRequestFactory authenticationRequestFactory = 
            new OpenSamlAuthenticationRequestFactory();
    authenticationRequestFactory.setAuthenticationRequestConverter((context) -> {
    }); // generate the authnRequest here
    return authenticationRequestFactory;
}

works for you?

Comment From: leneinz

Hi, @leneinz, thanks for the report.

You are correct that this approach only works with the AuthnRequest is unsigned. I think it's important to clarify that in the documentation.

Alternatively, you can configure the factory with setAuthenticationRequestContextConverter, which produces an AuthnRequest in the way that you expect.

I'll leave this ticket open for updating the documentation. Can you confirm that doing:

java @Bean public Saml2AuthenticationRequestFactory authenticationRequestFactory() { OpenSamlAuthenticationRequestFactory authenticationRequestFactory = new OpenSamlAuthenticationRequestFactory(); authenticationRequestFactory.setAuthenticationRequestConverter((context) -> { }); // generate the authnRequest here return authenticationRequestFactory; }

works for you?

This works! Thank you !