Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use OIDC standard claims, if result from mapping is null #2566

Closed
wants to merge 3 commits into from

Conversation

strehle
Copy link
Member

@strehle strehle commented Oct 23, 2023

With #1925 there was a fix already, however using custom claims can lead to error situations. With this fix, that error situations are prevented if standard claims in id_token, e.g. custom attribute is not in token, but family_name and given_name are also in the token as string. This fix is for OIDC IdP integration, therefore it makes sense to use as fallback also OIDC standard claims.

With #1925 there was a fix already, however using custom claims can lead to error situations.
With this fix, that error situations are prevented if standard claims in id_token, e.g. name is an array with different values,
but family_name and given_name are also in the token as string.
This fix is for OIDC IdP integration, therefore it makes sense to use as fallback also OIDC standard claims.
@cf-gitbot
Copy link

We have created an issue in Pivotal Tracker to manage this:

https://www.pivotaltracker.com/story/show/186311897

The labels on this github issue will be updated when the story is started.

@strehle strehle changed the title fix: User OIDC standard claims, if mapping is ambiguous fix: use OIDC standard claims, if mapping is ambiguous Oct 23, 2023
@strehle strehle added in_review The PR is currently in review and removed in_review The PR is currently in review labels Oct 26, 2023
@peterhaochen47 peterhaochen47 self-requested a review October 26, 2023 23:40
@peterhaochen47
Copy link
Member

peterhaochen47 commented Oct 27, 2023

I have concerns from an operator UX perspective.

Example of the exact impact of this PR (possibly in combination with the prior PR #1925 ):

Example attributeMappings in an external IDP config set by the operator:

    "attributeMappings" : {
...
      "given_name" : "preferred_first_name",
    # do not actually wish to map the phone number claim into UAA
...
    }

Example external token:

{
...
"given_name": "Bartholomew",
"phone_number": "123456789"
# does not actually have "preferred_first_name" claim for some reason (e.g. config mistake in their IDP "claim export" setting); the "preferred_first_name" would have been "Bart" if it was exported correctly
...
}

Resulting UAA token after this PR:

{
"given_name": "Bartholomew",
"phone_number": "123456789"
}

It seems to me that this PR would be "doing too much" for the operators by offering too much fallback mechanism.

If their intention is to have this mapping "given_name" : "preferred_first_name" and the mapped claim preferred_first_name is not found in the external token, it should be made obvious to them that their intended setting did NOT work, rather than offering them layers of opaque fallback mechanism to mask the problem. If I were the operator, I would rather see a NULL value for given_name in UAA token in this case so I know I need to fix this.

And if the operater's intention is to not import the phone number into UAA (by not adding an attributeMappings entry), then I would not want to import it for them.

Overall, if I were an operator, I would much rather have the actual UAA behaviors be completely deterministic based on my config, rather than having a lot of fallback & outcomes that I do not intend.

@strehle strehle added this to the icebox milestone Oct 27, 2023
@strehle
Copy link
Member Author

strehle commented Oct 27, 2023

Ok so the 2 fall back I see, however can we agree that we should have an option to get the OIDC name if no mapping is configured

Currently all admin have to configuration mappings and we have seen that these things can go wrong.

What we want have in future. There is scope in configuration already and in OIDC you can ask for scopes email and/or profile
-> scopes="openid email profile"

From a standard OIDC IdP you will get then automatically email, email_verified, given_name, family_name because these are the standard names, so in such cases a user attribute mapping should come automatically, ok ?

Return the oidc standard claim if the mapped claim is not in token.
This is useful needed if the mapping is not done or not correct.
If the mapping is available this is used.

The reality has shown, that many operators do not create a mapping at all or
correct mapping, but with OIDC the mapping for email, given_name, family_name is not
needed because they are there with scope profile.

See test getUser_doesNotReturnNullWhenIdTokenMappingIsNotAvailableButAlsoOidcStandardClaims
@strehle strehle changed the title fix: use OIDC standard claims, if mapping is ambiguous fix: use OIDC standard claims, if result from mapping is null Oct 27, 2023
@strehle
Copy link
Member Author

strehle commented Oct 27, 2023

@peterhaochen47 now only with one default, if custom mapping is null or if there is no custom mapping.

With that externalGroupMapping is not needed at all if profile scope is used and OIDC IdP behaves OIDC compliant

@peterhaochen47
Copy link
Member

peterhaochen47 commented Nov 1, 2023

Ok, now I agree that some defaulting based on the OIDC standard claims is fair. I think we can provide the following default values at the IDP config level (defaulting at the config level might also simplify our code here):

config.attributeMappings.email => email
config.attributeMappings.given_name => given_name
config.attributeMappings.family_name => family_name
config.attributeMappings.phone_number => phone_number
config.attributeMappings.email_verified => email_verified

Aka, if the operators DO NOT configure a mapping (left blank), then we use the above defaults.

But if the operators DO configure a mapping, but the mapping fails to get a valid claim from the external token, then I would argue that we should let it fail (and not fallback), so that the original intentions of the operators are respected. Going back to the above example:
Example attributeMappings in an external IDP config set by the operator:

    "attributeMappings" : {
...
      "given_name" : "preferred_first_name",
    # do not explicitly map the phone number claim into UAA
...
    }

Example external token:

{
...
"given_name": "Bartholomew",
"phone_number": "123456789"
# does not actually have "preferred_first_name" claim for some reason (e.g. config mistake in their IDP "claim export" setting); the "preferred_first_name" would have been "Bart" if it was exported correctly
...
}

Then I think the following resulting UAA token is fair:

{
"given_name": "NULL",
"phone_number": "123456789"
}

Since the operator did NOT set config.attributeMappings.phone_number, so we default it to the standard claim phone_number. But since the operator DID set "given_name" : "preferred_first_name" so I think we should respect that choice and be transparent that their intended config did not work.

@strehle strehle removed this from the icebox milestone Nov 2, 2023
@strehle
Copy link
Member Author

strehle commented Nov 2, 2023

ok, then cancel this

@strehle strehle closed this Nov 2, 2023
@strehle strehle deleted the fix/oidcClaimMappings branch November 2, 2023 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

3 participants