-
Notifications
You must be signed in to change notification settings - Fork 340
[FEATURE] usage of JWKS with JWT (w/o OpenID connect) #2708
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
[FEATURE] usage of JWKS with JWT (w/o OpenID connect) #2708
Conversation
stephen-crawford
left a comment
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 @sebastianmichalski, thank you for taking the time to put together this PR. I left a couple nit-picky comments and then also would appreciate it if you could expand your test to include an 'unhappy' scenario. Thank you for all your work! Generally things look good :)
src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java
Outdated
Show resolved
Hide resolved
src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java
Outdated
Show resolved
Hide resolved
...java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticatorTest.java
Outdated
Show resolved
Hide resolved
|
Hi @sebastianmichalski , I have a question in general about this change. The issue description mentions the use of I believe the Will this PR solve for the issue described in #1858 ? |
|
@cwperks You are mentioning a good point. Effectively, OpenSearch has two JWT authenticator implementations:
Even though one of these is called Thus, the requirement from #1858 can be very easily implemented in The other JWT authenticator, Thus, for kicking off the conversation, we have implemented the new feature in However, this needs some product mgmt decisions:
|
|
Hey @nibix , off the top of my head I think there are a few differences between these 2 backends. Here's a list of the settings that are available to the HTTPJwtAuthenticator:
|
|
@cwperks Thank you for the list! However, I think that the following attributes are already supported by
The attribute This leaves for following attributes which we can add
|
...ain/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticator.java
Outdated
Show resolved
Hide resolved
4548f09 to
b8c3889
Compare
Hey @nibix, Can you elaborate a little on why would the param |
src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java
Show resolved
Hide resolved
Codecov Report
@@ Coverage Diff @@
## main #2708 +/- ##
============================================
+ Coverage 61.47% 61.54% +0.06%
- Complexity 3403 3407 +4
============================================
Files 266 266
Lines 18865 18881 +16
Branches 3302 3302
============================================
+ Hits 11598 11620 +22
+ Misses 5673 5663 -10
- Partials 1594 1598 +4
|
The signing keys now come from the referenced JWKS. |
src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java
Outdated
Show resolved
Hide resolved
cwperks
left a comment
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 @sebastianmichalski . This will need to be accompanied with documentation to instruct users to use OIDC auth backend for simple JWT authentication with a JWKS config instead of using the JWT backend. It would be nice if this could be extended to the JWT backend as the issue describes, but this solution does solve the request from the issue filed.
DarshitChanpura
left a comment
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.
LGTM overall. Left some nit comments.
src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java
Outdated
Show resolved
Hide resolved
src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java
Outdated
Show resolved
Hide resolved
src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java
Outdated
Show resolved
Hide resolved
src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java
Show resolved
Hide resolved
3600474 to
cba1c92
Compare
DarshitChanpura
left a comment
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.
LGTM. The comment about extracting the hard-coded values is not a blocker from merging.
|
@sebastianmichalski Quick question: Is it possible to add an integration test to show required audience and required issuer working with OIDC backend? |
5c5902e to
fb37040
Compare
Is this test not sufficient? https://github.com/opensearch-project/security/pull/2708/files#diff-7495fb84f47dfc4449f13b5a9eb8cc3ea42e5b5a58529ef133e373947918bb2fR64 |
|
@sebastianmichalski How about a negative test? The backend is configured with required issuer, but the token does not contain the claim? Same for required audience? Let me know what you think. |
fb37040 to
1f57328
Compare
| Assert.assertFalse(creds.getAttributes().get("attr.jwt.iss").contains(jwtAuth.getRequiredIssuer())); | ||
| } | ||
|
|
||
| @Test |
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 trying to understand, based on the equivalent test in HTTPJwtAuthenticatorTest it looks like this should be returning null creds because if the audience claim in the token is different from the configured requiredAudience then it would not be considered a valid token. Since the creds are not null here, does that mean it would successfully authenticate?
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.
The reason that the one You found is providing null instead of AuthCredentials is that we are using different extractCredentials0() method (from HTTPJwtAuthenticator instead of AbstractHTTPJwtAuthenticator). The one more verbose is trying to parse claims and checks ie. audience, while the other one in the same time just takes claims from token without any checks there (or at least the checks agains audience/issuer):
jwtParser.parseClaimsJws(jwtToken) throws Exception which leads to return null; in line 205:

in the meantime jwt.getClaims(); is just returning the claims which are just validated only against signature, expiry and nbf.
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.
Is this testing to ensure that if the user presents a token that was signed with a verifiable signature, but contains a mismatching audience claim that the request is unauthorized?
If a user has in their authc: list:
openid_auth_domain:
http_enabled: true
transport_enabled: true
order: 0
http_authenticator:
type: openid
challenge: false
config:
subject_key: preferred_username
roles_key: roles
jwks_uri: <jwks_uri>
required_issuer: keycloak
authentication_backend:
type: noop
and sends a JWT with an HTTP Request that was signed with the same, JWKS but with claims
{
'sub: '<username>',
'roles: '<role1>,<role2>',
'iss: 'auth0',
...
}
would that request be rejected? I don't see any logic in this PR that would deny that request and I understand that we are just so happening to be adding support for required_issuer and required_audience here even though this PR is introducing support for jwks_uri.
Does there need to be any additional logic here to check if the issuer in the claims matches the required issuer and if the audience in the claims matches the required audience?
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.
The topic of this issue was to just provide jwks_uri to use it instead of changing signing key manually I guess, not to change current plugin behavior. Should we change this behavior within this issue?
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.
That's what I took @nibix comment to mean here. There is no need to add required_issuer and required_audience in this PR if they are config options for the OIDC backend, but do nothing. I'm also happy to accept this PR introducing the config options and fast-follow it to wire them up and make them useful.
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.
@cwperks I have to apologize for the irritation here. Of course, having required_audience and required_issuer as config attributes needs the accompanying logic. We will add this logic ASAP.
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.
Sure, now it's doable when I know what to do with those params 😉
adad554 to
512bcaa
Compare
Signed-off-by: Sebastian Michalski <shekerama@gmail.com>
512bcaa to
052836e
Compare
|
@sebastianmichalski @nibix Would you be able to merge the latest from |
| String issuer = claims.getIssuer(); | ||
|
|
||
| if (!audience.equals(requiredAudience)) { | ||
| throw new JwtException("Invalid issuer"); |
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.
Can this exception text be updated to read Invalid audience?
| public void jwksMissingRequiredAudienceInClaimTest() { | ||
| Settings settings = Settings.builder() | ||
| .put("jwks_uri", mockIdpServer.getJwksUri()) | ||
| .put("required_issuer", TestJwts.TEST_ISSUER) |
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.
Should this read required_audience here?
|
Closing in lieu of #2808. Thank you for your effort @sebastianmichalski! |
Description
Extending auth with jwks_uri parameter to omit passing openid_connect_url with openid-configuration
Issues Resolved
#1858
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.