-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Improve authoritiesClaimName validation in JwtGrantedAuthoritiesConverter #17247
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
base: main
Are you sure you want to change the base?
Improve authoritiesClaimName validation in JwtGrantedAuthoritiesConverter #17247
Conversation
…rter Use StringUtils.hasText() instead of null check to properly handle empty strings and whitespace-only strings. Signed-off-by: chanbinme <[email protected]>
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.
Thanks for the PR, @chanbinme! I've left my feedback inline.
@@ -106,7 +106,7 @@ public void setAuthoritiesClaimName(String authoritiesClaimName) { | |||
} | |||
|
|||
private String getAuthoritiesClaimName(Jwt jwt) { | |||
if (this.authoritiesClaimName != null) { | |||
if (StringUtils.hasText(this.authoritiesClaimName)) { |
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.
Instead of continuing to check for null
, let's remove the null check by doing the following:
- Change the
authoritiesClaimName
toCollection<String> authoritiesClaimNames = WELL_KNOWN_AUTHORITIES_CLAIM_NAMES;
- Change
setAuthoritiesClaimName
to setthis.authoritiesClaimNames
to a single value - Replace the for loop to use
this.authoritiesClaimNames
- Remove the null check
In this way, authoritiesClaimNames
can never contain an empty claim name.
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.
Hi @jzheaux,
I've implemented the refactoring as suggested, but I noticed an important behavioral difference that I wanted to discuss:
Original behavior:
- When
authoritiesClaimName
is explicitly set → return it directly without JWT validation - When using default claim names → return the first claim name that exists in the JWT
Initial refactoring attempt:
- All claim names go through JWT validation, which changes the behavior for explicitly set claim names
My solution:
To preserve the original behavior, I added an isExplicitlySet
flag that tracks whether the claim name was explicitly configured. This ensures:
- Explicitly set claim names are returned without JWT validation (original behavior)
- Default claim names are validated against the JWT (original behavior)
- Null checks are eliminated since
authoritiesClaimNames
is always initialized
Would you prefer this approach, or would you like to intentionally change the behavior to always validate claim names against the JWT? I wanted to confirm the intended behavior before finalizing the implementation.
The changes include:
- ✅ Changed
authoritiesClaimName
toCollection<String> authoritiesClaimNames
- ✅ Updated
setAuthoritiesClaimName
to useCollections.singletonList()
- ✅ Modified the for loop to use
this.authoritiesClaimNames
- ✅ Removed null checks
- ➕ Added
isExplicitlySet
flag to preserve original behavior
Let me know your thoughts on this approach!
...framework/security/oauth2/server/resource/authentication/JwtGrantedAuthoritiesConverter.java
Show resolved
Hide resolved
...work/security/oauth2/server/resource/authentication/JwtGrantedAuthoritiesConverterTests.java
Outdated
Show resolved
Hide resolved
- Change authoritiesClaimName field to Collection<String> authoritiesClaimNames - Add isExplicitlySet flag to preserve original behavior - Remove null checks by ensuring authoritiesClaimNames is always initialized - Maintain backward compatibility for explicit vs default claim name handling - Delete unnecessary test code related to previous null-checking logic Signed-off-by: chanbinme <[email protected]>
b6b8aa0
to
39b5cf5
Compare
Hi @jzheaux, Thank you so much for your helpful feedback! Thanks again for your time and support! |
Summary
Use
StringUtils.hasText()
instead of null check ingetAuthoritiesClaimName()
to properly handle empty strings and whitespace-only strings.Problem
The current null check (
!= null
) incorrectly treats empty strings (""
) and whitespace-only strings (" "
) as valid claim names. WhilesetAuthoritiesClaimName()
validates withAssert.hasText()
, the field can be set through other means (reflection, constructors, etc.) that bypass this validation.Changes
!= null
check withStringUtils.hasText()
Testing
Added parameterized tests covering empty strings, whitespace strings, and null values using
ReflectionTestUtils
to simulate edge cases.Impact
This is a straightforward bug fix that improves robustness without breaking changes.