Uploaded image for project: 'OpenAM'
  1. OpenAM
  2. OPENAM-11966

saml2 SSO 'better' auth'n comparison fails with 'Invalid status code in response'



    • Bug
    • Status: Resolved
    • Minor
    • Resolution: Fixed
    • 13.5.1, 14.1.0, 14.1.1
    • 13.5.2, 6.0.0, 14.1.2, 5.5.2
    • authentication, SAML
    • OpenAM v5.1. Customer upgraded from 13.5.0
    • Rank:
    • AM Sustaining Sprint 44, AM Sustaining Sprint 45
    • 3
    • Yes
    • No
    • Yes, No
    • Yes and I used the same an in the description


      Bug description

      When SAML SSO authentication comparison is set to 'better' on hosted SP, SP initiated SSO fails with message 'Invalid status code in response'.

      How to reproduce the issue

      Using https://backstage.forgerock.com/docs/am/5/saml2-guide/#chap-saml2-implementation-console as reference, performed the following in OpenAM 13.5.0, 13.5.1 and AM 5.1:

      1. Performed initial configuration for two OpenAM instances, idp.amtest1.com and sp.amtest1.com. Both use host cookies (idp.amtest1.com and sp.amtest1.com).
      2. Configured a hosted IdP in idp.amtest1.com using 'test' signing key, 'test_idp' circle of trust, mail -> mail attribute mapping.
      3. Configured a hosted SP in sp.amtest1.com using COT test_sp.
      4. Created a remote SP in idp.amtest1.com, attr mapping mail -> mail.
      5. Created a remote IdP in sp.amtest1.coma
      6. In sp.amtest1.com, created a saml2 auth'n module, and an auth'n chain which included the saml2 module as Required.
      7. For the realm / in sp.amtest1.com, set User Profile as dynamic.
      8. Created two test subjects, including a mail address attribute value for each.
      9. In sp.amtest1.com, modified hosted SP to change ACS service endpoints from .../Consumer/... to .../AuthConsumer/...  Did the same for remote SP in idp.amtest1.com.
      10. In sp.amtest1.com, enabled auto-federation, using mail as attribute.
      11. In sp.amtest1.com, set Default Auth'n context to unspecified, Authn comparison as 'better' and enabled the following Context References: unspecified, level 0; PasswordProtected, 5; Kerberos, level 10; and MobileTwoFactorUnregistered, 20.
      12. In idp.amtest1.com, mirrored the above SP settings for Authentication Context, enabling each of the above as Modules, with the same levels as above.  Default auth'n contextset to unspecified.
      13. In separate browser, performed SP initiated SSO.  Navigated to https://sp.amtest1.com:7443/access?service=saml2Chain.  In 13.5.0, this results in being able to login at IdP and am taken to a created profile page for authenticated user in SP.  In 13.5.1 and 5.1 (14.1), navigation to above url results in error message in browser 'Invalid status code in response'.
      14. Using a SAML tracer plugin to browser, for the error case above, in 13.5, first saml request response includes:
      • <saml2p:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/><saml2p:RequestedAuthnContext Comparison="better"><saml2:AuthnContextClassRef xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml2:AuthnContextClassRef></saml2p:RequestedAuthnContext></saml2p:AuthnRequest>
      • In 13.5.1 and above, the above response includes the status NoAuthnContextSpecified.
      Expected behaviour
      The flow should match that seen in 13.5.0
      Current behaviour
      'better' authentication comparison value is resulting in an SSO failure.

      Work around

      Customer has modified configuration to use exact match.  This enables successful SSO for the above scenario in 5.1

      Code analysis

      Issue looks to be in 

      lines 131... 143
      if (!"better".equals(comparison) && classRefSchemesMap.containsKey(requestedClassRef)) {
          classRef = requestedClassRef;
      } else if (classRef != null) {
          List<String> singleClassRef = Collections.singletonList(requestedClassRef);
          for (String configuredRef : classRefSchemesMap.keySet()) {
              if (isAuthnContextMatching(singleClassRef, configuredRef, comparison, realm, idpEntityID)) {
                  classRef = configuredRef;
      In the above case, 'better' skips past if block and then, because classRef i still set to null, also skips past else.  Result is that classRef is left at null resulting in the status code being set to NoAuthnContextSpecified.
      For this scenario, code needs to call isAuthnContextMatching, so that an evaluation of a better than 'unspecified' authentication context can be performed.  In 13.5.0 code, this returns the first in the list - MobileTwoFactorUnregistered as its the first one which has a level greater than unspecified's 0.



          Issue Links



              lawrence.yarham Lawrence Yarham
              lawrence.yarham Lawrence Yarham
              0 Vote for this issue
              2 Start watching this issue