-
Notifications
You must be signed in to change notification settings - Fork 291
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
Extend JWT Signing Algorithms to Support RSA and EC #2805
Extend JWT Signing Algorithms to Support RSA and EC #2805
Conversation
Codecov Report
@@ Coverage Diff @@
## main #2805 +/- ##
============================================
+ Coverage 63.24% 63.36% +0.12%
- Complexity 3452 3474 +22
============================================
Files 263 264 +1
Lines 20053 20130 +77
Branches 3348 3352 +4
============================================
+ Hits 12683 12756 +73
- Misses 5741 5746 +5
+ Partials 1629 1628 -1
|
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
@@ -123,6 +127,38 @@ static JsonWebKey createJwkFromSettings(Settings settings) throws Exception { | |||
} | |||
} | |||
|
|||
private static JsonWebKey getSigningJwk(String algorithm, Settings settings) throws Exception { |
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.
Hey @MaciejMierzwa, I also wanted to add a link to how this is configured for the SAML backend. The SAML backend is very generic and let's any configured properties be added to the JWK. Idk if that area should be updated to match the logic here to have a pre-defined list of properties or if it makes sense to match the logic there to read in any configured settings: https://github.com/opensearch-project/security/blob/main/src/main/java/com/amazon/dlic/auth/http/saml/AuthTokenProcessorHandler.java#L265-L297
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's already added by Ryan in his original implementation. It should allow to load non-pre-defined config. It would just adhere to library standards, which just implement naming from the documentation. If no config with our keys is present, then we could load config looking like this:
{
"kty":"RSA",
"n":"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddx
HmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMs
D1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSH
SXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdV
MTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8
NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ",
"e":"AQAB",
"d":"Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97I
jlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0
BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn
439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYT
CBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLh
BOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ",
"p":"4BzEEOtIpmVdVEZNCqS7baC4crd0pqnRH_5IB3jw3bcxGn6QLvnEtfdUdi
YrqBdss1l58BQ3KhooKeQTa9AB0Hw_Py5PJdTJNPY8cQn7ouZ2KKDcmnPG
BY5t7yLc1QlQ5xHdwW1VhvKn-nXqhJTBgIPgtldC-KDV5z-y2XDwGUc",
"q":"uQPEfgmVtjL0Uyyx88GZFF1fOunH3-7cepKmtH4pxhtCoHqpWmT8YAmZxa
ewHgHAjLYsp1ZSe7zFYHj7C6ul7TjeLQeZD_YwD66t62wDmpe_HlB-TnBA
-njbglfIsRLtXlnDzQkv5dTltRJ11BKBBypeeF6689rjcJIDEz9RWdc",
"dp":"BwKfV3Akq5_MFZDFZCnW-wzl-CCo83WoZvnLQwCTeDv8uzluRSnm71I3Q
CLdhrqE2e9YkxvuxdBfpT_PI7Yz-FOKnu1R6HsJeDCjn12Sk3vmAktV2zb
34MCdy7cpdTh_YVr7tss2u6vneTwrA86rZtu5Mbr1C1XsmvkxHQAdYo0",
"dq":"h_96-mK1R_7glhsum81dZxjTnYynPbZpHziZjeeHcXYsXaaMwkOlODsWa
7I9xXDoRwbKgB719rrmI2oKr6N3Do9U0ajaHF-NKJnwgjMd2w9cjz3_-ky
NlxAr2v4IKhGNpmM5iIgOS1VZnOZ68m6_pbLBSp3nssTdlqvd0tIiTHU",
"qi":"IYd7DHOhrWvxkwPQsRM2tOgrjbcrfvtQJipd-DlcxyVuuM9sQLdgjVk2o
y26F0EmpScGLq2MowX7fhd_QJQ3ydy5cY7YIBi87w93IKLEdfnbJtoOPLU
W0ITrJReOgo1cq9SbsxYawBgfp_gh6A5603k2-ZQwVK0JKSHuLFkuQ3U"
}
for RSA which is also ok since it's well documented
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.
Hey @MaciejMierzwa , I'd like to revisit this thread. In the SAML Authentication Response handler it creates a JWT and will use the exchange_key
from the saml authenticator settings in the authc:
section of the security config. Example:
authc:
saml_auth_domain:
http_enabled: true
transport_enabled: false
order: 1
http_authenticator:
type: saml
challenge: true
config:
idp:
metadata_file: metadata.xml
entity_id: http://idp.example.com/
sp:
entity_id: https://opensearch-dashboards.example.com
kibana_url: https://opensearch-dashboards.example.com:5601/
roles_key: Role
exchange_key: 'peuvgOLrjzuhXf ...'
authentication_backend:
type: noop
Inside of the logic where it generates the token there is an else
block that takes any settings under key
and sets them as properties for the JWK. It looks like the logic is kept very generic to provide as much flexibility as possible to the cluster admin configuring the SAML authenticator. Do you think that logic is too generic and should be better validated like you are doing in this PR or should this On Behalf Of authenticator have the same flexibility as its done in the SAML authenticator?
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 @MaciejMierzwa, did you get a chance to see this comment above? I know you shared some code earlier that looked like it had some updates. Did you get a chance to push those changes?
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java
Outdated
Show resolved
Hide resolved
src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.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.
Overall looks really close. I just wanted to check with you about what you thought for documentation and also see whether you can add checks for all the algorithms. I know it may seem like overkill, but in theory we should test all the algorithms we offer.
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.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.
Thank you @MaciejMierzwa ! This is quite thorough and the tests cover the different configuration options. I left a few comments around the ease of configuration and let me know what you think.
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
a520210
to
1a8de74
Compare
Settings jwkSettings = settings.getAsSettings("jwt").getAsSettings("key"); | ||
|
||
if (algorithm != null) { | ||
return getSigningJwk(algorithm.toUpperCase(), settings); |
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.
return getSigningJwk(algorithm.toUpperCase(), settings); | |
return getSigningJwk(algorithm.toUpperCase(Locale.ROOT), settings); |
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 @MaciejMierzwa, overall looks very good. Just a few minor comments. Let's try to work together to drive this to close.
jwk.setPublicKeyUse(PublicKeyUse.SIGN); | ||
jwk.setKeyType(KeyType.OCTET); | ||
String signingKey = Optional.ofNullable(settings.get("signing_key")).orElseThrow(() -> new IllegalArgumentException("Settings for signing key is missing. Please specify at least the option signing_key with a shared secret.")); |
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.
We will want to document this; we can add a table or something with the supported keys and explain secret creation.
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/securityconf/impl/v7/ConfigV7.java
Outdated
Show resolved
Hide resolved
src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java
Outdated
Show resolved
Hide resolved
e7a801a
to
cf8d2c9
Compare
f7cf41a
to
d6685df
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.
This looks good to me after the CI issues are resolved. Excellent job with the tests!
@MaciejMierzwa LGTM. Once you resolve merge conflicts, this should be good to go. |
I've re-written the description of this change and the title of the pull request to be more accessible to the community |
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.
There is another pull request that is merging feature/extension to main [1], that leaves this change in a strange place.
@RyanL1997 since you are handling this branch what next steps do you recommend?
src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java
Outdated
Show resolved
Hide resolved
Hi @MaciejMierzwa and @peternied, I'm pushing the merge into main for now. And that PR (#3179 ) is very close for merging, so should we await for the merging of that PR and change point this PR to main? |
Hi @MaciejMierzwa, just a friendly reminder that we can reference this PR directly to main branch according to the merge of #3179. The feature branch will be cleaned up and deleted soon. |
The base branch was changed.
Hi @RyanL1997 since this branch was based on branch feature/extensions there are a lot of commit's that didn't made yet to main. What do you think about dropping most of the commits beside mine and letting commits from feature/extensions be pulled in later? |
Signed-off-by: Maciej Mierzwa <dev.maciej.mierzwa@gmail.com>
6c07d83
to
d2f3003
Compare
Signed-off-by: Maciej Mierzwa <dev.maciej.mierzwa@gmail.com>
d2f3003
to
f5c92b1
Compare
# Conflicts: # build.gradle
Signed-off-by: Maciej Mierzwa <dev.maciej.mierzwa@gmail.com>
@MaciejMierzwa I think we should put this PR on hold until after the JWT library swap [1] has been addressed. Maybe this would be a good one to sync up offline |
Closing PR for now as we are leaving it in the back burner for now. |
Description
Previously, the application was limited to HMAC-based algorithms (HS256, HS384, HS512). With this update, RSA and Elliptic Curve algorithms are now supported as well.
Supported Algorithms:
The new feature enables users to configure the signing method by specifying JSON Web Keys (JWK) in the configuration, modeled after their JSON structure, or by directly using private RSA/EC keys. This aligns with the algorithms specified in RFC 7518 Section 3.1.
Issues Resolved
#2680
Testing
Unit tests prepared with focus on EC and SHA JWT creation
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.