Improve RemoteJWKSet - additional requirements and with example implementation
Hi, we have for some time used a JWK cache which has a few more features than the current implementation in this project. Now we would like to see whether contributing some of the features to this project is feasible. In a nutshell, the features are
- rate-limited remote fetch on unknown key id
- health indicator support
- transient retry on network problems
-
lazy or proactive background refresh
- in background thread
-
cache with improved logging for corner cases
This currently a synchronious (non-reactive) implementation, implemented as a layered set of classes with builders and various custom exceptions (modelled after Auth0s approach).
Note that
- the implementation uses locks for synchronization, executors for background work
- the rate-limited on remote fetch option can be improved; the user should select a strategy for refresh (frequent or infrequent + on demand)
- an adaptation already exists (some refactoring would be needed)
Comments (16)
-
-
reporter Java 8+ features, very good question, I did not catch the Java 7 compatiblity. I’ll give it a test run on 7 and get back to you. Now the library is currently at Java 8, and has a dependency on bucket4j which is Java 8 too. I am thinking that 7 compatibility will be straightforward, but would also welcome a Java 8 branch.
Would you prefer the logging used java.util.logging.Logger? I would like to keep (most) of the logging, at least for informing the user that sertificates are about to expire (when the authorization server is down) and when threads are waiting (blocked) due to waiting for network requests.
-
reporter Java 7 is feasible, I have a Maven build running the tests from command line.
Summary:
- need to implement a simple leaky bucket type throttling, Bucket4J is Java 8 and also the additional footprint cannot be justified
- unit tests needs to extend TestCase and use the classic approach for testing exceptions. Some assertions probably need rewriting.
- time / duration must be reduced to milliseconds (which is fair and less bloated anyways)
- junit and mockito downgrades
- some default methods in interfaces need copying into implementations
More adjustments are left in order for the code to follow the existing project conventions / tidy up dependencies etc, but this is looking good so far.
I must admit that I have not missed the Java 7 all that much, this was like a walk down memory lane. This would perhaps be as a good as any to start a Java 8 branch.
-
The Java 7 lang level has been primarily kept to enable Android app developers to ship code with this lib that works with older versions of the OS. Having said that, every now and then we get queries to Connect2id support whether we could back port some recent lib release Java 6 to suit some legacy JBoss deployment :)
I personally don’t feel good about modifying your piece of code so that it becomes compatible with java 7. Two possibilities I see:
- Create a new Java 8 module for this new logic.
- Start a new Java 8 branch and merge the new code there.
What do you think about that? Pros / cons?
-
reporter I refactored the code into a Java 7 version, see this PR.
For Java 8 and Android, perhaps you want to stay compatible with the subset of Java 8 supported by using
com.android.tools:desugar_jdk_libs
. -
Thanks a lot, I’ll check it out!
-
Hi guys, what is the current status of this issue ? any plans for having this merged and released ?
-
reporter @Francisco Bento everything lives in this PR and has undergone several rounds of revision and adjustments. The code is ready for merge as far as I understand.
-
The new feature is getting an article with examples on the lib site this week and then we’ll be good to go with release
-
Thank you @Thomas Skjønberg and the team for the superb work.
Im currently hacking the current version to have some health indicator support on my spring boot/security based app. Looking forward to see your changes going to spring-security-oauth2-resource-server, interested specially on the rate-limited remote fetch of unknown kids.
@Yavor Vasilev , what are the plans for the next version iteration ? Will it be a major version bump ?
-
The article can be sneak peeked now, the new release is coming out later today.
https://connect2id.com/products/nimbus-jose-jwt/examples/enhanced-jwk-retrieval
-
- changed status to resolved
On to Maven Central as
version 9.28 (2023-01-05) * New JWKSourceBuilder entry point for building JWKSource instances that wrap a generic JWKSetSource with caching (including refresh ahead), rate limiting, retrial, fail-over, health status reporting and outage tolerance capabilities. * New CachingJWKSetSource, RefreshAheadCachingJWKSetSource, RateLimitedJWKSetSource, RetryingJWKSetSource, JWKSourceWithFailover, JWKSetSourceWithHealthStatusReporting and OutageTolerantJWKSetSource classes wrapping a generic JWKSetSource with a capability. * Deprecates the JWKSetCache interface and its DefaultJWKSetCache implementation. * Deprecates the RemoteJWKSet class. * Deprecates the JWKSetWithTimestamp class. * DefaultResourceRetriever adds support for file based URLs. * New JWKSet isEmpty and size shorthand methods. * New com.nimbusds.jose.util.cache package with generic CachedObject class. * New com.nimbusds.jose.util.events package with Event and EventListener interfaces. * New com.nimbusds.jose.util.health package with HealthReportListener interface, HealthReport class and HealthStatus enum. * New IOUtils.closeSilently(java.io.Closeable) method.
-
reporter Thank you Vladimir & team!
-
It was a pleasure :)
If you wish to have an affiliation or something else added to the credit let us know:
https://connect2id.com/products/nimbus-jose-jwt#thanks
Cheers!
-
reporter Cheers, the current text is good, but please also add my employer Entur using a link to our Github account: https://github.com/entur, like so:
Thomas Rørvik Skjølberg at Entur for contributing a powerful mini framework for retrieving JWK sets with caching, outage, retrial and fail-over capabilities.
Let me know if you’re going to Oslo some time in the future, I’ll buy the beers.
-
Here it is: https://connect2id.com/products/nimbus-jose-jwt#thanks !
Now I only need to figure out a good “business” reason for a trip to Oslo lol
- Log in to comment
Thank you very much for considering this contribution. It is seldom that the library receives more complete and substantial enhancements. The majority tend to focus on very specific issues. Btw, the day day I joked on Twitter that this is becoming less of a library for cryptography and more for networking and caching. The RemoteJWKSet received several such related changes recently.
I did a first quick scan of the code.
To what extent does the code rely on Java 8+ features? At present the library targets Java 7. However, for some there have been thoughts to start a new Java 8 branch, and put it out eventually as a new major release.
I also noticed that there is a logging dependency. So far the approach has been to keep logging out, but provide enough context and ability to hook logging when people want that.