IDP Breaking Change in 8.1.2 AD/AD Hybrid Failover

Hi,

We use an Active Directory user source, which returns all the roles from AD. Problem is you cannot assign a badge to a user in a pure AD user source.

We then used a soft failover AD Internal Hybrid to assign the user badges, as originally recommended by @jspecht.

This worked really well until 8.1.2 as when a user logged in with a badge, the user would be found in the hybrid failover source, matched to a user in the pure AD source and return with the AD groups as roles. Similar to below:

{
  "tokenEndpointResponse": {
    "access_token": "<accesstoken>",
    "id_token": "<token>",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "openid"
  },
  "idTokenClaims": {
    "iss": "<idp name>",
    "aud": "ignition",
    "exp": 1612952433,
    "jti": "<jti>",
    "iat": 1612951833,
    "nbf": 1612951713,
    "sub": "<username>",
    "preferred_username": "<username>",
    "roles": [
      "all",
      "the",
      "roles",
      "from",
      "AD"
    ],
    "nonce": "<nonce>",
    "email": "<email>",
    "given_name": "<name>",
    "family_name": "<surname>",
    "amr": [
      "badge"
    ],
    "auth_time": 1612951058,
    "challenged": false
  }
}

Now, after upgrade to 8.1.2, it returns an empty list for roles if authenticated against the soft failover.

How can we restore this critical functionality, other than rolling back to 8.1.1?
If we can assign a badge to a users to a pure AD user source, that would be ideal. We can replicate the user roles assignment in AD Hybrid source as that is not maintainable at scale.

Please assist.

Regards,
Deon

The changes in 8.1.2 indeed would break the workaround we came up with back then, unfortunately.

The only other workaround that comes to mind is something recently discussed here: IdP/Database Hybrid

In short: you can use an expression attribute mapper which invokes a jython script to fetch the roles of the user from the pure AD source given the username of the user which is returned from the OIDC token claims.

Let me know if that helps

Hi Joel,

Thanks for the prompt reply.

I get the intention of the expression: get the roles from another user source based on the username of this requesting user?

runScript("system.user.getUser('Active Directory', '" + {idp-attributes:/saml2p:Response/saml2:Assertion/saml2:Subject/saml2:NameID/text()} + "').getRoles()")

This bit:

{idp-attributes:/saml2p:Response/saml2:Assertion/saml2:Subject/saml2:NameID/text()} 

is over my paygrade. Is this the correct syntax for the response of the Ignition idP?

I’ll give it a go.

Regards,
Deon

For the Ignition IdP, this should work for you:

runScript("system.user.getUser('Active Directory', '" + {attribute-source:idTokenClaims:preferred_username} + "').getRoles()")

I got it a second before you posted!

It seems to work. Will test a bit more.

Thanks for the help

1 Like

It seems the roles are correctly pulled from the ‘Active Directory’ user source through the expression attribute mapping, but the security level rules no longer evaluate true.

image

image

I assumed the {idp-attributes:roles} refer to the mapped attributes. Does this need to change?

Try swapping

{idp-attributes:roles}

with

runScript("system.user.getUser('Active Directory', '" + {attribute-source:idTokenClaims:preferred_username} + "').getRoles()")