Allow wrapper-controlled init to fix jwk_uri backward compatibility (Issue #3054)#3198
Allow wrapper-controlled init to fix jwk_uri backward compatibility (Issue #3054)#3198sh1myama wants to merge 2 commits intoAthenZ:masterfrom
Conversation
Signed-off-by: Shuya Shimaoka <sshimaok@lycorp.co.jp>
Summary of ChangesHello @sh1myama, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a critical backward compatibility issue where the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request refactors the initialization logic in AuthZpeClient by moving the access token resolver setup to an explicit init() method, which resolves issues with jwk_uri system properties and introduces support for a JWK proxy URI. However, a high-severity Server-Side Request Forgery (SSRF) vulnerability has been identified due to a lack of URL validation for the new JWK proxy URI feature; implementing a strict allow-list for proxy servers is recommended. Furthermore, the new init() method has a potential thread-safety issue and should be made idempotent to prevent race conditions during concurrent initialization.
| public static void init() { | ||
| if (LOG.isDebugEnabled()) { | ||
| LOG.debug("Init: load the ZPE"); | ||
| } | ||
| // initialize the access token signing key resolver | ||
|
|
||
| initializeAccessTokenSignKeyResolver(); |
There was a problem hiding this comment.
The new init() method is not thread-safe or idempotent. If called concurrently (e.g., during application startup or in parallel tests), it can lead to race conditions during the initialization of static resources. It's a best practice to ensure that initialization methods like this execute only once.
You can make this method thread-safe and idempotent by using a static flag with double-checked locking. This will ensure the initialization logic is performed safely and exactly one time.
Example:
// Add this field to the class
private static volatile boolean zpeInitialized = false;
// Modify the init() method
public static void init() {
// Quick check without lock
if (zpeInitialized) {
return;
}
synchronized (AuthZpeClient.class) {
// Check again inside the synchronized block
if (zpeInitialized) {
return;
}
if (LOG.isDebugEnabled()) {
LOG.debug("Init: load the ZPE");
}
// ... current init logic ...
initializeAccessTokenSignKeyResolver();
// ... other set calls that were moved ...
zpeInitialized = true;
}
}|
@sh1myama the AuthZpeClient.init() was never required for ZPE functionality. So by moving the actual keyresolver initialization into that function will break most zpe users, so not the correct solution. I'll check in the next couple of days in more detail and will propose how to address your use case. |
|
@havetisyan -san
Thank you for checking. In the following Java decentralized access control sample, the documentation says to initialize the ZPE Client in init when performing authorization checks, so I understood that calling init is mandatory. Even if we apply this change and modify it so that initializeAccessTokenSignKeyResolver is called from init, my understanding is that the behavior will not change as long as the implementation is written to always call init itself. Thank you in advance. |
|
@sh1myama here is what changes we need to make:
this would allow your applications to set the either set the jwks_uri to complete the sign key resolver or jwks_uri_required to false in your application and ignore calling the method completely. |
|
@havetisyan -san |
Signed-off-by: Shimpei Yamazaki <shimyama@lycorp.co.jp>
7a5fdc4 to
0f2569c
Compare
|
@havetisyan -san |
|
|
||
| setMillisBetweenZtsCalls(Long.parseLong(System.getProperty(ZPE_PROP_MILLIS_BETWEEN_ZTS_CALLS, Long.toString(30 * 1000 * 60)))); | ||
| if (tokenSignKeyResolverInitialized) { | ||
| setMillisBetweenZtsCalls(Long.parseLong(System.getProperty(ZPE_PROP_MILLIS_BETWEEN_ZTS_CALLS, Long.toString(30 * 1000 * 60)))); |
There was a problem hiding this comment.
let's move this setMillisBetweenZtsCalls as the last line in the initializeAccessTokenSignKeyResolver method. this way we don't have to repeat the call twice once here and then once again in init method
Description
Context
Changes
Outcome
Contribution Checklist:
Attach Screenshots (Optional)