SAML Providers and the authn_context Property

When the Akamai Identity Cloud released custom identity providers, one of the supported protocols for new IdPs was (and still is) the Security Assertion Markup Language (SAML) 2. And the protocol wasn’t just supported: for the vast majority of Identity Cloud customers, and for the vast majority of SAML-based social login providers, the Identity Cloud’s initial SAML release has worked remarkably well.

That said, however, there have been a few exceptions to this success story, and here's why. By default, the Identity Cloud’s SAML solution includes the RequestedAuthnContext element in each authentication request (with the class for the element set to PasswordProtectedTransport and the comparison type set to exact).  Without going into detail, this means that, when sending a SAML authentication request, the Identity Cloud asks that the user be authenticated solely by using a username and password. In general, this hasn’t been a problem, at least in part because many IdPs simply ignore the RequestedAuthnContext element and authenticate the user the way they want to authenticate the user. (As the name implies, RequestedAuthnContext requests an authentication methodology, but IdPs are free to ignore that request.) 

However, this approach can cause problems if: 1) an IdP doesn’t ignore the RequestedAuthnContext element, and, 2) that IdP can’t authenticate users only by using a username and password. (For example, an identity provider might require multi-factor authentication, which goes beyond just a username and password.) With Microsoft Azure, for example, some user authentications have failed with an error similar to this:

AADSTS75011: Authentication method 'WindowsIntegrated' by which the user authenticated with the service doesn’t match requested authenticated method 'PasswordProtectedTransport’

In the preceding example, the user has already been authenticated, but by using something other than the requested authentication method (PasswordProtectedTransport). For example, the user initially logged on by using multi-factor authentication, or by using a smart-card. Regardless, if the initial authentication didn’t use PasswordProtectedTransport the user’s attempt to log on to Azure will be rejected.

To help organizations avoid this issue, the Identity Cloud has modified the way SAML requests are made. As noted, previously the Identity Cloud’s SAML requests used the RequestedAuthnContext element, with the class set to PasswordProtectedTransport and the comparison type set to exact. As of August 12, 2021, that’s no longer the case. Instead:

  • Any new SAML providers you configure have the RequestedAuthnContext element set to a null value. That means that your SAML providers won’t request a specific authentication method and, as a result, they're unlikely to have authentication requests rejected because theIdP doesn't support the requested methodology.

    Note. If you create a new provider and then use the Configurable IdP APIs to return the property values pf the provider, you probably won’t see the authn_context property in the API response. That’s because the property isn't enabled by default.

  • SAML providers created before August 12, 2021 will continue to use the RequestedAuthnContext element: these providers were left as-is following the age-old advice that “if it ain’t broke, don’t fix it.” If you use the Configurable Provider APIs to return the properties values of an existing SAML provider, those property values will include the following:
    "authn_context": {
      "comparison": "exact",
      "class_ref": "PasswordProtectedTransport"
    }
  • For both new SAML providers and for older SAML providers, you can use the authn_context property to enable or disable the RequestedAuthnContext element. Are you running into AADSTS75011-like authentication errors with providers with your SAML IdPs? Then you might want to disable the authn_context setting. Do you have a SAML IdP that expects to see the RequestedAuthnContext element and expects it to be set to PasswordProtectedTransport? (Somewhat-unlikely, but possible.) In that case, you might have to enable the setting. Toggling this setting as-needed should allow organizations to work seamlessly with most (if not all) of the major SAML2 providers.



Configuring the authn_context Setting

So what exactly does it mean to enable or disable the authn_context setting? Let’s start by looking at a slightly-truncated set of property values for an “old” (i.e., pre-August 12, 2021) SAML provider:

"auth_url": "https://akamai-technologies---assets-46464.login.go.akamai-access.com/saml/idp/sso",
"authn_context": {
  "comparison": "exact",
  "class_ref": "PasswordProtectedTransport"
},
"createdAt": "2021-05-05T21:08:23.596479762Z",
"id": "34abcbc2-fb8b-427a-a4d8-6c7dd5b2f43b",
"protocol": "saml2",
"title": "Akamai SAML",
"ui": {
  "title": "Akamai SAML",
  "icon_url": "https://dyzz9obi78pm5.cloudfront.net/app/image/id/5b749261ec161c506163b298/n/mixi-logo.svg"
    },

As you can see, the authn_context property is enabled with the old default settings: the class_ref is equal to PasswordProtectedTransport and the comparison is set to exact. That means that the authentication request includes the RequestedAuthnContext element.

And that leads to an important question that we should address right now: what should you do if this SAML provider is working just fine? In that case, we recommend that you don’t do anything at all: if the provider is working then there’s no reason to change it. As we mentioned earlier, many IdPs simply ignore the RequestedAuthnContext element anyway: in cases like that, it doesn’t matter whether authn_context is enabled or not. If you created a SAML provider prior to August 12, 2021 and that provider is working just fine, well, the best thing you can do is this: nothing.

But let’s suppose that this provider isn’t working as expected, let’s suppose you’re getting errors similar to the AADSTS75011 error generated by Azure. In that case, you can use the Custom Provider APIs and the PATCH method to set authn_context to a null value. For example, here’s a Curl command that does just that:

curl -L -X PATCH \
  'https://v1.api.or-stg.janrain.com/3cc14467-fd4f-437d-a0c0-0b3888dd2ee4/v2/config/low/services/engage-v2/apps/fifbclhccfpjdeoejkag/custom-providers/34abcbc2-fb8b-427a-a4d8-6c7dd5b2f43b' \
  -H 'Content-Type: application/merge-patch+json' \
  -H 'Authorization: Bearer UY-a_0yKfiDWpfBzDKurFXGykLveEwYbzUOHltC-CwMy4zMpmrs5egmhNUcvBpoS' \
  --data-raw '{
    "authn_context": null
  }'

When you disable the authn_context property two things happen. First, and most obvious. the authn_context property is set to null. Second, and most important, the RequestedAuthnContext element is no longer included in your SAML authentication requests. That should enable your provider to work with Azure and with other IdPs that honor RequestedAuthnContext requests.

And what if you need to enable the RequestedAuthnContext element? Well, before you go down that road, keep these two things in mind:

  • At this point in time, PasswordProtectedTransport is the only schema supported by the Identity Cloud.: that means that enabling authn_context won’t do you any good if you need to use a schema like Public Key – PGP or SmartcardPKI.

  • The only comparison allowed right now is exact. Other comparison values (minimum, maximum, better) aren’t supported.

Which simply means that you can disable authn_context by setting the value to null, or you can enable the authn_context setting only by using this syntax:

"authn_context": {
  "comparison": "exact",
  "class_ref": "PasswordProtectedTransport"
}

A fully-fleshed out Curl call for enabling this setting will look similar to this:

curl -L -X PATCH \
  'https://v1.api.or-stg.janrain.com/3cc14467-fd4f-437d-a0c0-0b3888dd2ee4/v2/config/low/services/engage-v2/apps/fifbclhccfpjdeoejkag/custom-providers/34abcbc2-fb8b-427a-a4d8-6c7dd5b2f43b' \
  -H 'Content-Type: application/merge-patch+json' \
  -H 'Authorization: Bearer UY-a_0yKfiDWpfBzDKurFXGykLveEwYbzUOHltC-CwMy4zMpmrs5egmhNUcvBpoS' \
  --data-raw '{
   "authn_context": {
      "comparison": "exact",
      "class_ref": "PasswordProtectedTransport"
    }
}'