-
Notifications
You must be signed in to change notification settings - Fork 257
feat: new claimsService and new merge behavior #881
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
Conversation
Codecov ReportBase: 77.69% // Head: 77.92% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #881 +/- ##
==========================================
+ Coverage 77.69% 77.92% +0.23%
==========================================
Files 44 45 +1
Lines 1690 1708 +18
Branches 331 335 +4
==========================================
+ Hits 1313 1331 +18
Misses 340 340
Partials 37 37
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
|
Nice work! Only some small things to fix... |
|
The intent is to merge the identity claims in the id_token and the userinfo endpoint. And it's difficult to merge those if you have duplicates/conflicts in the sets of values (which unfortunately some token servers do). But those values "merged" all in one place are useful. The merge used to work fairly well, then at some point someone came along and submitted a PR (of course, for their specific scenario) that actually made things worse for most everyone else. I am pretty sure I reverted it, but I don't recall now, so the state of things might have not been ideal. |
|
At the end it might be better to not merge at all, but store both claims objects within the user object. Something like: Like this the user of the library can decide what is the best to choose and we could still calculate an additional |
|
Well, the original implementation was decent, so you might check the history and compare to what it does now. But what I'd suggest then is to leave how it used to work (pre-PR I mentioned) and then make that extensible so people can override if needed. I still suggest putting it all in one place is important, as it shields the client code from needing to understand the details of claim in the id_token vs claims in the user info endpoint. And that might change as well in the token server based on config, something which the client logic will benefit being shielded from. |
I came to the same conclusion. Lets keep this simple and stupid. In case of merging the only question is; what is happening with arrays. Currently we are aggregating them, which is not the best solution (e.g.
I am not so sure if the current aggregate array behavior makes sense in the long run... |
|
@pamapa, do not forget about the upcoming We will have 2 use cases:
In case 2, we might have received something in the IdToken at the beginning that is no more true in the new UserInfo (like a role that was removed to the user). So in this case : array -> substract |
The idea is work there only with Maybe it makes sense for the |
if openid is not true (no "openid" in scope), means there is no id_token. Thus userInfo will be the first to start the user.profile |
Userinfo doesn't exist without OIDC, and thus there is no user profile without OIDC. |
|
So, trying to recap: 3- merge function will be used in both "signin scenario" and "refreshuserinfo scenario", with the same behavior Questions: (I'll have to close both this PR and the other one since the desiderata is quite different from what I implemented. I hope to be able to work on this soon.) |
|
|
So! The new "merge behavior" was not so different from what was originally implemented in this PR. I
Hopefully, this is good to go. I see there are some conflicts, let me know if you need me to rebase. |
|
please resolve the conflicts otherwise i can not start the unit-tests... |
f6d2a5b to
1d76800
Compare
|
@pamapa Rebased, squashed and ready to go. |
| * Otherwise, they are added to an array as distinct objects for the claim type. (default: false) | ||
| * @deprecated since version 2.3.0. It's not a deterministic way of handling claims. | ||
| */ | ||
| mergeClaims?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it makes sense to keep this settings in the long turn in the way it was supposed:
From the description:
Indicates if objects returned from the user info endpoint as claims (e.g. `address`) are merged into the claims from the id token as a single object.
Otherwise, they are added to an array as distinct objects for the claim type. (default: false)
-> true = merged, false = added/appended as an array (the otherwise clause).
-> mergeClaims = true -> the new behavior of array handling
-> mergeClaims = false -> the legacy behavior
We keep the default as is and in a major release we change the default to true.
The mergeClaimsLegacyBehavior is then not needed
What do you think? Does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we agree on the above it makes sense to rename legacyMergeClaims to appendClaims, remove if (typeof value === "object" && this._settings.mergeClaims) {... and not call it from mergeClaims. Instead we make and if/else on the caller side depending on mergeClaims.
-> easier to understand and easier to follow the unit-tests.
iff we want to keep the if (typeof value === "object" && this._settings.mergeClaims) {... -> if (typeof value === "object" && this._settings.mergeClaimsLegacyBehavior) {...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pamapa frankly I just want this implementation to go ahead.
The current behavior is wrong, wherever we spin it we will have some breaking changes unless we create new attributes to keep this wrong behavior.
Right now mergeClaims, when enabled, works as a deep merging mechanism, which we will have by default in the new implementation, and changing its meaning will break some usage somewhere.
Whichever solution makes it clearer for you makes sense to me, I'll stick to the new implementation and try to forget about all of this ASAP, but we have 40 comments on this PR and I think we need to land it somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Badisi Should we keep the setting mergeClaims=false in the long run? aka to allow the append mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll stick to the new implementation and try to forget about all of this ASAP
I will help you here. First step see #904
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @marcoreni that this whole mergeClaims thing is wrong from the start and that it's taking us too much discussion. TBH I don't even recall why we were talking about rewriting it at the first place. I thought that @marcoreni requirement was only to be able to reload UserInfo ?
So do we have any issue today with this merge mechanism ? If not then I would suggest to leave it as is, as it seems to work well for everybody (else we would have had other complains). And if we really need to refactor it I would go with a mergeClaimsStrategy=['none','merge','replace'] (or something alike), not so disruptive and with all use cases covered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
requirement was only to be able to reload UserInfo
will not work with the current wrong merge behavior...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused..
- The first time,
IdTokenwill be merged withUserInfodata. - The second time (when asking to refresh user info), we will use the current
IdTokenand merge it with the newly receivedUserInfodata.
This should be exactly the same.. why it wouldn't work ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Badisi You are right lets stop this merge request for now. And implement the feature like you said.
Merging claims is not perfect, we can change that later...
|
@marcoreni Are you still interested to land this? I am not planing a 3.0.0, as such we can make breaking changes, lets focus your engineered algorithm of merging and drop the current merging + drop the mergingClaims settigs.... |
Closes/fixes
Checklist
First chunk of #877 splitting. This PR introduces the new merge behavior and moves all the claims related logic inside a dedicated service