-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
ClaimAccessor#getClaimAsMap doesn't return null as documented #10117
Comments
Thanks for pointing this out, @shartte. It would be odd for Are you able to submit a PR to update the Javadoc for |
Sure, I can do that. Are you sure they shouldn't return null? Depends on what an app should do with claims they can't process. There's no X.509-style "MustUnderstand" in JWT, so I am honestly unsure. |
If it returns If you want to do a trial conversion, you can always get the claim yourself and try to convert: Object value = this.accessor.getClaim("myclaim");
TypeDescriptor type = TypeDescriptor.map(Map.class,
TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Object.class))
Map<String, Object> map = ClaimConversionService.getSharedInstance().convert(value, type);
if (map == null) {
// try something else
} |
Well, there's still edit: But this is largely a theoretical discussion :) |
sounds good! In case it's helpful, I'll share a couple more reasons why Spring Security favors returning an error in situations like these. If coercion fails, it's probably due to a coding or configuration error. In security-related code, we'd prefer that devs find out about those problems early in the dev cycle, and returning an error is a reliable way to do that. It also means that for a production error, devs have fewer steps to finding out what's wrong, and they didn't need to do anything special to get that benefit. It's also quite similar to how casting and autoboxing work in Java. If Java fails to do it, you get an error. Consider the Map<String, Object> claims = Collections.singletonMap("myclaim", Instant.now());
ClaimAccessor accessor = () -> claims;
String value = accessor.getClaim("myclaim"); Which is the least astonishing: For the above to error (since the value isn't a You can see another example of this preference in |
No need to convince me, I am using Nimbus JSONObjectUtil for conversion of the remaining claims anyhow, and they decided to use checked exceptions to communicate this. |
@shartte Regarding your original comment, I don't see an issue with Given the claim:
A call to java.lang.IllegalArgumentException: Unable to convert claim 'claim' of type 'class java.lang.String' to Map. This is the correct behaviour. However the javadoc can be confusing:
The text in bold is where the confusion may be. The following javadoc should clear things up: /**
* Returns the claim value as a {@code Map<String, Object>} or {@code null} if it does not exist.
* @param claim the name of the claim
* @return the claim value or {@code null} if it does not exist
* @throws IllegalArgumentException if the claim value cannot be converted to a {@code Map<String, Object>}
*/ What do you think? |
Update ClaimAccessor#getClaimAsMap and ClaimAccessor#getClaimAsStringList JavaDoc according to the current implementation Closes spring-projectsgh-10117
Add tests for ClaimAccessor#getClaimAsMap and ClaimAccessor#getClaimAsStringList Closes spring-projectsgh-10117
Add tests for ClaimAccessor#getClaimAsMap and ClaimAccessor#getClaimAsStringList Issue gh-10117
Update ClaimAccessor#getClaimAsMap and ClaimAccessor#getClaimAsStringList JavaDoc according to the current implementation Closes gh-10117
Describe the bug
org.springframework.security.oauth2.core.ClaimAccessor#getClaimAsMap
's Javadoc reads as follows:The actual implementation throws an
IllegalArgumentException
instead, if the claim value cannot be converted to a map:This may affect other methods on this class as well, but I only tested this one.
To Reproduce
Use a claim value such as:
Then call
getClaimAsMap("claim")
and observe that the following exception will be thrown:Expected behavior
The Javadoc should match the actual implementation, or vice versa.
The text was updated successfully, but these errors were encountered: