-
Notifications
You must be signed in to change notification settings - Fork 280
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
[ELY-2574] Add ability to configure additional scope for authentication request #1925
Conversation
Thanks @PrarthonaPaul. Since this PR is against the wildfly-elytron project, the title, commit message, and description should be referencing an ELY issue. |
@PrarthonaPaul Were you able to get |
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfigurationBuilder.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfigurationBuilder.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcJsonConfiguration.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcJsonConfiguration.java
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcJsonConfiguration.java
Show resolved
Hide resolved
Yes I was able to run OidcTest as well as a full build with tests successfully. |
This is the failure from the CI log:
Might be good to check if maybe you have some local changes that weren't pushed. |
rerunning tests right now. |
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
Outdated
Show resolved
Hide resolved
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
Outdated
Show resolved
Hide resolved
@PrarthonaPaul Looks like the commits need to be cleaned up a bit so that they all reference the ELY issue and looks like things can be squashed too. |
http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTClientSecretCredentialsProvider.java
Outdated
Show resolved
Hide resolved
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcBaseTest.java
Outdated
Show resolved
Hide resolved
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 updates @PrarthonaPaul! I've added some feedback.
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
Outdated
Show resolved
Hide resolved
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
Outdated
Show resolved
Hide resolved
297ac11
to
d0902d5
Compare
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
Outdated
Show resolved
Hide resolved
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
Outdated
Show resolved
Hide resolved
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
Outdated
Show resolved
Hide resolved
d0902d5
to
c9a589b
Compare
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
Outdated
Show resolved
Hide resolved
91442a1
to
620fd0d
Compare
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfigurationBuilder.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfigurationBuilder.java
Outdated
Show resolved
Hide resolved
public static OidcClientConfiguration buildWithoutUnsupportedAttributes(String unsupportedAttributesParam, InputStream is) { | ||
OidcJsonConfiguration oidcJsonConfiguration = loadOidcJsonConfiguration(is); | ||
try { | ||
failIfUnsupportedAttribute(unsupportedAttributesParam, oidcJsonConfiguration); |
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.
Just wondering if it's possible to detect the unsupported attribute somehow during loadOidcJsonConfiguration
rather than after the OidcJsonConfiguration
has been created?
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 want it to be inside loadOidcJsonConfig
to save parsing time, then don't think so, because loadOidcJsonConfig() uses adapterConfig = mapper.readValue(is, OidcJsonConfiguration.class);
. And since scope is a jsonProperty defined in the OidcJsonConfiguration class, it would not fail.
But if we want to do something like
adapterConfig = mapper.readValue(is, OidcJsonConfiguration.class);
check for scope inside adapterConfig and fail if scope is not null
then yes, we can do that.
But I am not sure if that simplifies the code any more. The reason why I added a new function is so that we still have a build(InputStream is)
function.
If we handle the scope check inside loadOidcJsonConfiguration, then we will instead need to add something like loadOidcJsonConfigurationWithoutUnsuppportedAttributes(InputStream is, String unsupportedOidcAttributes)
Please feel free to let me know if that is cleaner though. I am okay with changing it.
http/oidc/src/main/java/org/wildfly/security/http/oidc/ElytronMessages.java
Outdated
Show resolved
Hide resolved
@PrarthonaPaul I think hold off for a bit on making updates based on my latest comments. Am looking closer to see if there's a different way we could handle this. |
620fd0d
to
70e83ee
Compare
@@ -66,7 +67,7 @@ public void contextInitialized(ServletContextEvent sce) { | |||
if (is == null) { | |||
oidcClientConfiguration = new OidcClientConfiguration(); | |||
} else { | |||
oidcClientConfiguration = OidcClientConfigurationBuilder.build(is); | |||
oidcClientConfiguration = OidcClientConfigurationBuilder.buildWithoutUnsupportedAttributes(is, servletContext.getInitParameter(JSON_CONFIG_UNSUPPORTED_ATTRIBUTE_PARAM)); |
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.
@PrarthonaPaul I've looked more closely into this and have an alternative suggestion for us to consider.
Instead of needing to update Elytron so that it can cope with attributes that are not supported by the default stability level in WildFly, I think we can add handling in OidcActivationProcessor
in the elytron-oidc-client
subsystem. In particular, I think we could do the following:
- In
OidcActivationProcessor
, we can get theWEB-INF/oidc.json
file from the deployment as follows:deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT).getRoot().getChild("WEB-INF/oidc.json")
. - That gives us a
VirtualFile
that we could then read the contents of to end up with aString
. - We could then add handling to
OidcActivationProcessor#deploy
such that if the stability level isn't the community stability level (i.e.,! deploymentUnit.getStability().enables(Stability.COMMUNITY)
), then if the contents contain the specific attributes that are only available at the community stability level, deployment should fail. Otherwise, theString
can be used to set theJSON_CONFIG_CONTEXT_PARAM
servlet context param so that when theOidcClientConfiguration
is being built, we won't read from theoidc.json
file a second time, we'll just make use of the String we already have.
WDYT of this approach?
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 think it is cleaner if in WildFly we can do the stability level validation as stability levels are a WildFly concern not an Elytron concern.
If I am reading this suggestion correctly are we talking about being able to parse from the String directly?
Maybe as a follow up later on another option could be when the Processor in WildFly calls these APIs it can also pass in some predicate for validation?
But for now +1 on constraining to WildFly if we can.
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.
Right, this suggestion is to parse from the String directly in OidcActivationProcessor
in WildFly.
As a follow up, we could try to pass in a predicate that would be used for validation. We'd likely need to create a class that extends com.fasterxml.jackson.core.JsonFactory
to be able to make use of the predicate when parsing in OidcClientConfigurationBuilder#loadOidcJsonConfiguration
.
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 move the predicate option to a Jira issue we can follow up later and decide if we want to do that.
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've created https://issues.redhat.com/browse/ELY-2737 to track this.
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 have updated the code for handling unsupported attributes for deployment config and removed the old code.
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
Outdated
Show resolved
Hide resolved
http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
Outdated
Show resolved
Hide resolved
String scopes = jwtClaims.getClaimValueAsString("scope"); | ||
if (scopes != null) { | ||
if (scopes.contains("email")) { | ||
assertTrue(jwtClaims.getClaimValueAsString("email_verified").contains(String.valueOf(KeycloakConfiguration.EMAIL_VERIFIED))); |
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.
It seems that Keycloak will set the email
and profile
scopes by default so just wondering if checking only email_verified
and profile
are actually enough to successfully test that the configured scopes have been set properly. As an example, I tried tweaking testMultipleScopeValue
locally to only set the openid
scope. I would have expected the test to fail in this case however it actually ended up passing. Is there a claim that we could check that would only be set if a specific scope other than the default ones has been configured?
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.
Looks like the address
claim is a candidate for a claim that would confirm that the configured scopes are being used as expected, i.e., we could update tests to also specify the address
scope. Then, the JWT claims will include the address
claim as well. This claim isn't included by default so this would confirm that the configured scopes are actually getting used as expected.
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 don't think we can do address, because org.keycloak.representations.idm.UserRepresentation
does not have a way to set that. Plus when I added address as a scope, the request timed out.
I saw this earlier with this API as well when I wanted to set offline_access
as one of the scopes. It is kind of limiting in that 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.
However, I can change the default list of scopes for the client to just OpenID, so that the results of those scopes are only included if the config asks for it.
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 tried adding address
locally and was able to see the address
added in the claims. So even if we can't actually set a value for it, we can still verify that it's present in the claims. This allows us to verify that setting the scope value actually resulted in the correct behaviour. With the test as is right now, we can't be sure that setting the scope actually had an effect since the current claims that are being tested will be present regardless of the scope configuration.
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.
However, I can change the default list of scopes for the client to just OpenID, so that the results of those scopes are only included if the config asks for it.
Yes another option would be to change the default list of scopes if that's easy to do. I quickly tried that yesterday but wasn't able to get things working as expected but maybe I was missing something.
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.
Yeah, I am trying that now and I am getting a class cast exception.
I am looking more into it to see what is causing that.
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 was able to fix this. I added openid as the default scope and the others needed to be added as optional scopes.
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.
Thank you for this update! The tests look great now!
One last comment (that won't block merging either) is that right now we're checking if the scope from the JWT claims contains a certain value and then checking that value. Instead, it would be better to use the expectedScope
String instead. It should be possible to do that by passing the expectedScope
to getCallbackHandler
instead of passing the boolean value.
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.
Fixed!
d582ef7
to
a3fa083
Compare
http/oidc/src/test/java/org/wildfly/security/http/oidc/KeycloakConfiguration.java
Outdated
Show resolved
Hide resolved
7eded8d
to
6353159
Compare
6353159
to
fc56044
Compare
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 very much @PrarthonaPaul!
https://issues.redhat.com/browse/ELY-2574