Jwks RSA - JSON Web Key Set parser.

Related tags

Security jwks dx-sdk
Overview

jwks-rsa

CircleCI Maven Central FOSSA Status

Install

Maven

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>jwks-rsa</artifactId>
    <version>0.17.0</version>
</dependency>

Gradle

implementation 'com.auth0:jwks-rsa:0.17.0'

Usage

The JSON Web Tokens you get from the Authorization Server include a key id header parameter ("kid"), used to uniquely identify the Key used to sign the token.

i.e.: Given the following JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlJrSTVNakk1T1VZNU9EYzFOMFE0UXpNME9VWXpOa1ZHTVRKRE9VRXpRa0ZDT1RVM05qRTJSZyJ9.eyJpc3MiOiJodHRwczovL3NhbmRyaW5vLmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1NjMyNTAxZjQ2OGYwZjE3NTZmNGNhYjAiLCJhdWQiOiJQN2JhQnRTc3JmQlhPY3A5bHlsMUZEZVh0ZmFKUzRyViIsImV4cCI6MTQ2ODk2NDkyNiwiaWF0IjoxNDY4OTI4OTI2fQ.NaNeRSDCNu522u4hcVhV65plQOiGPStgSzVW4vR0liZYQBlZ_3OKqCmHXsu28NwVHW7_KfVgOz4m3BK6eMDZk50dAKf9LQzHhiG8acZLzm5bNMU3iobSAJdRhweRht544ZJkzJ-scS1fyI4gaPS5aD3SaLRYWR0Xsb6N1HU86trnbn-XSYSspNqzIUeJjduEpPwC53V8E2r1WZXbqEHwM9_BGEeNTQ8X9NqCUvbQtnylgYR3mfJRL14JsCWNFmmamgNNHAI0uAJo84mu_03I25eVuCK0VYStLPd0XFEyMVFpk48Bg9KNWLMZ7OUGTB_uv_1u19wKYtqeTbt9m1YcPMQ

Decode it using any JWT library or tool like jwt.io and extract the kid parameter from the Header claims.

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg"
}

Use this kid on any of the JwkProviders enumerated below to obtain the signing key provided by the JWKS endpoint you've configured.

UrlJwkProvider

UrlJwkProvider fetches the jwk from /.well-known/jwks.json of the supplied domain issuer and returns a Jwk if the kid matches one of the registered keys.

JwkProvider provider = new UrlJwkProvider("https://samples.auth0.com/");
Jwk jwk = provider.get("{kid of the signing key}"); //throws Exception when not found or can't get one

Also it can load jwks.json file from any given Url (even to a local file in your filesystem).

JwkProvider provider = new UrlJwkProvider(new URL("https://samples.auth0.com/"));
Jwk jwk = provider.get("{kid of the signing key}"); //throws Exception when not found or can't get one

GuavaCachedJwkProvider

GuavaCachedJwkProvider cache the jwk in a LRU in memory cache, if the jwk is not found in the cache it will ask another provider for it and store it's result in the cache.

By default it stores 5 keys for 10 minutes, but these values can be changed.

JwkProvider http = new UrlJwkProvider("https://samples.auth0.com/");
JwkProvider provider = new GuavaCachedJwkProvider(http);
Jwk jwk = provider.get("{kid of the signing key}"); //throws Exception when not found or can't get one

RateLimitJwkProvider

RateLimitJwkProvider will limit the amounts of different signing keys to get in a given time frame.

By default the rate is limited to 10 different keys per minute but these values can be changed.

JwkProvider url = new UrlJwkProvider("https://samples.auth0.com/");
Bucket bucket = new Bucket(10, 1, TimeUnit.MINUTES);
JwkProvider provider = new RateLimitJwkProvider(url, bucket);
Jwk jwk = provider.get("{kid of the signing key}"); //throws Exception when not found or can't get one

JwkProviderBuilder

To create a provider for domain https://samples.auth0.com with cache and rate limit:

JwkProvider provider = new JwkProviderBuilder("https://samples.auth0.com/")
    .build();
Jwk jwk = provider.get("{kid of the signing key}"); //throws Exception when not found or can't get one

and specifying cache and rate limit attributes:

JwkProvider provider = new JwkProviderBuilder("https://samples.auth0.com/")
    .cached(10, 24, TimeUnit.HOURS)
    .rateLimited(10, 1, TimeUnit.MINUTES)
    .build();
Jwk jwk = provider.get("{kid of the signing key}"); //throws Exception when not found or can't get one

Error handling

There are certain scenarios in which this library can fail. Read below to understand what to expect and how to handle the errors.

Missing JSON Web Key

This error may arise when the hosted JSON Web Key set (JWKS) file doesn't represent a valid set of keys, or is empty. They are raised as a SigningKeyNotFoundException. The cause would need to be inspected in order to understand the specific failure reason.

Network error

There's a special case for Network errors. These errors represent timeouts, invalid URLs, or a faulty internet connection. They may occur when fetching the keys from the given URL. They are raised as a NetworkException instance.

If you need to detect this scenario, make sure to check it before the catch of SigningKeyNotFoundException.

try {
    // ...
} catch (NetworkException e) {
    // Network error
} catch (SigningKeyNotFoundException e) {
    // Key is invalid or not found
}

Unsupported JSON Web Key

When the received key is not of a supported type, or the attribute values representing it are wrong, an InvalidPublicKeyException will be raised. The following key types are supported:

  • RSA
  • Elliptic Curve
    • P-256
    • P-384
    • P-521

Rate limits

When using a rate-limited provider, a RateLimitReachedException error might be raised when the limit is breached. The instance can help determine how long to wait until the next call would be available.

try {
    // ...
} catch (RateLimitReachedException e) {
    long waitTime = e.getAvailableIn()
    // wait until available
}

What is Auth0?

Auth0 helps you to:

  • Add authentication with multiple authentication sources, either social like Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others, or enterprise identity systems like Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider.
  • Add authentication through more traditional username/password databases.
  • Add support for linking different user accounts with the same user.
  • Support for generating signed Json Web Tokens to call your APIs and flow the user identity securely.
  • Analytics of how, when and where users are logging in.
  • Pull data from other sources and add it to the user profile, through JavaScript rules.

Create a free Auth0 Account

  1. Go to Auth0 and click Sign Up.
  2. Use Google, GitHub or Microsoft Account to login.

Issue Reporting

If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.

Author

Auth0

License

This project is licensed under the MIT license. See the LICENSE file for more info.

FOSSA Status

Comments
  • com.auth0.jwk.SigningKeyNotFoundException: Cannot obtain jwks from url https://<oauth_server>/.well-known/jwks.json

    com.auth0.jwk.SigningKeyNotFoundException: Cannot obtain jwks from url https:///.well-known/jwks.json

    I am trying to validate incoming request that has authorization token (jwt) via Java JWT api. I was able to decode header and payload via that API but having trouble to validate the token. Little I know of this area, I thought I have to add jwks-rs-java api to my test project in order to handle validation part so I imported and ran following statements based on the documentation I read.

    JwkProvider provider = new UrlJwkProvider("oauth_Server"); Jwk jwk = provider.get("keyId");

    Then I got SingingKeyNotFoundException but caused by javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

    I am trying to understand the problem itself and how to rectify it. Did I provide wrong key id? Do I need to import a certificate of the remote "oauth_server" into my local box in where I build/execute project in IDE?

    I'd appreciate your advice and input on this matter. Thank you!

    opened by jwtLearner 14
  • Distinct between connection issues and attacks in UrlJwkProvider

    Distinct between connection issues and attacks in UrlJwkProvider

    Describe the problem you'd like to have solved

    Hi there in UrlJwkProvider a SigningKeyNotFoundException is thrown in the method "Jwk get(String keyId)" for two different reasons:

    1. If in getAll()-> getJwks() the connection to the location of the JWK fails. Which is an serious issue for operation of the service, as most likely all token could not be verified)
    2. If the KeyId in the token could not be found. (most likely if an attacker sets an arbitrary key id in the token)

    Describe the ideal solution

    Please make it possible to distinct between these two cases with a proper exception being thrown. To not break any existing code, which is calling the methods, the new exception should be a child class of SigningKeyNotFoundException or a RuntimeException.

    Alternatives and current work-arounds

    A current workaround will be to look at the cause of the exception, which is a fragile, as one has to know which specific connection issues could occur and that there is no other place, where such an exception could be thrown.

    An alternative of the approach above will be to change the return type of "Jwk get(String keyId)" to "Optional get(String keyId)" that there is a distinction between the the more common case, where a key with the wrong keyId is requested an an exceptional connection problem. This will involve more rework.

    Thank you for considering this change.

    enhancement waiting for customer 
    opened by JoergAdler 12
  • Add proxy

    Add proxy

    Changes

    • Added methods to UrlJwkProvider and JwkProviderBuilder
    • Careful not to modify existing method signatures or remove methods - change is backwards compatible
    • We are using this library in an isolated network setting where some calls must go through an HTTP/HTTPS proxy, and other calls must not.
    • This change is needed for use cases such as ours where we want to send this HTTP/HTTPS call through a proxy, but we don't want to set the global System Properties (which would impact other HTTP/HTTPS calls that we do not want to go through the same proxy as these calls must).

    References

    I have recreated PR #91 - I totally messed up my branch and wanted to start with a clear PR so I wouldn't be pushing this change as a bunch of garbage commits, and instead keep the file history simple and clean.

    Testing

    To test, simply invoke the new builder method and supply a proxy server. It can be as simple as: new java.net.Proxy(java.net.Proxy.Type.HTTP, new java.net.InetSocketAddress("proxy.mydomain.com", 8080))

    • [X] This change adds test coverage
    • [ ] This change has been tested on the latest version of Java or why not
    • [X] This change has been developed on Amazon Corretto 8, and uses a fairly simple Java API that has been around since Java 5

    Checklist

    CH: Added 
    opened by JosephWitthuhnTR 11
  • Add proxy

    Add proxy

    Changes

    • Added methods to UrlJwkProvider and JwkProviderBuilder
    • Careful not to modify existing method signatures or remove methods - change is backwards compatible
    • We are using this library in an isolated network setting where some calls must go through an HTTP/HTTPS proxy, and other calls must not.
    • This change is needed for use cases such as ours where we want to send this HTTP/HTTPS call through a proxy, but we don't want to set the global System Properties (which would impact other HTTP/HTTPS calls that we do not want to go through the same proxy as these calls must).

    References

    I am not aware of any references. We identified this as a need for our projects and have been working around the proxy limitation locally, but we wanted to contribute this change back rather than maintain it as our own "side fix/enhancement" for the issue.

    Testing

    To test, simply invoke the new builder method and supply a proxy server. It can be as simple as: new java.net.Proxy(java.net.Proxy.Type.HTTP, new java.net.InetSocketAddress("proxy.mydomain.com", 8080))

    • [ ] This change adds test coverage
    • [ ] This change has been tested on the latest version of Java or why not
    • [X] This change has been developed on Amazon Corretto 8, and uses a fairly simple Java API that has been around since Java 5

    Checklist

    opened by JosephWitthuhnTR 10
  • GuavaCachedJwkProvider vs UrlJwkProvider

    GuavaCachedJwkProvider vs UrlJwkProvider

    Use of GuavaCachedJwkProvider together with UrlJwkProvider could be improved.

    As an URL can contain several sertificates (UrlJwkProvider.getAll()), the whole cache can be refreshed rather than one key at a time.

    Lets imagine that some tokens are issued for certificate A. Something happens and the certificate owner invalidates certificate A and and issues certificate B. Then the cache will continue to validate tokens signed with certificate A even after visiting the URL for getting certificate B.

    closed:stale 
    opened by skjolber 9
  • Provide a getPrivateKey method in Jwk

    Provide a getPrivateKey method in Jwk

    Description

    Signing JWT tokens will become easier if the Jwk class were to have a createPrivateKey method, similar to its getPublicKey method. The returned private key could be used in a KeyProvider, which in turn can be used to create an algorithm with the capability to sign JWT tokens.

    Like you already used for the public key, the RFC states which parameters should be used for creating its private counterpart. I would expect the method to raise an error if the jwk does not contain the correct parameters to create a private key.

    Prerequisites

    Environment

    Please provide the following:

    • Version of this library used: 0.7.0
    • Version of Java used: 11
    • Additional libraries that might be affecting your instance: -
    enhancement closed:stale 
    opened by mjduijn 9
  • Feature Request: Full URLs in Builder Constructor

    Feature Request: Full URLs in Builder Constructor

    Hi,

    would it not be useful if the constructor of the convenience class JwkProviderBuilder would also accept a URL? Currently it is unusable for situations where the URL differs from the standard pattern (ending with "/.well-known/jwks.json"). It assumes, that the given string is only the domain-name and "/.well-known/jwks.json" is appended.

    PS: I thought I write a feature request before implementing it myself and starting a pull request.

    Cheers and thanks for your work, Dobo

    opened by totev 9
  • BucketImpl is not public

    BucketImpl is not public

    BucketImpl is not public so I cannot use rate limiting without using JwkProviderBuilder. (Also I cannot set a connect and read timeout with JwkProviderBuilder, otherwise I would have just used it).

    e.g. this is impossible:

    JwkProvider url = new UrlJwkProvider("https://samples.auth0.com/"); Bucket bucket = new Bucket(10, 1, TimeUnit.MINUTES); JwkProvider provider = new RateLimitJwkProvider(url, bucket);

    enhancement closed:stale 
    opened by jmferland 8
  • Issue #20 added url constructor to JwkProviderBuilder

    Issue #20 added url constructor to JwkProviderBuilder

    • URL constructor added to JwkProviderBuilder, which allows to customize the url to get JWKS. Before, it could only be <domain>/.well-known/jwks.json, now it can be <domain>/sub/path/.well-known/jwks.json
    • In case url is null IllegalStateException is thrown, so the behavior is similar to the String constructor
    • Unfortunately, I didn't find a good way to move JwkProviderBuilder.normalizeDomain to UrlJwkProvider keeping the same behavior
    • Slight fixes for JavaDocs
    • Please, let me know if more tests required
    opened by darthvalinor 8
  • com.auth0.jwk.Jwk#getPublicKey recreates PublicKey object on every access

    com.auth0.jwk.Jwk#getPublicKey recreates PublicKey object on every access

    Even when using a cached JwkProvider, the com.auth0.jwk.Jwk#getPublicKey method will reconstruct a public key object in memory on every call.

    Although the caching prevents remote calls, at high volumes (eg thousands requests/sec, each requiring JWT verification) this amount of object allocation creates a measureable overhead.

    feature request 
    opened by adrian-skybaker 7
  • Add JDK 9+ / modules support

    Add JDK 9+ / modules support

    Describe the problem you'd like to have solved

    Using this library deterministicly as an dependency in a JDK 9+ project; fixing the module name.

    Describe the ideal solution

    Multi-release jar.

    Alternatives and current work-arounds

    Automatic-Module-Name goes a long way.

    opened by skjolber 7
  • NetworkException not being thrown when using cached JwkProviderBuilder instead of directly UrlJwkProvider

    NetworkException not being thrown when using cached JwkProviderBuilder instead of directly UrlJwkProvider

    Describe the problem

    As per: examples we should be able to catch NetworkException when getting JWK using cached JwkProviderBuilder. But in here that error is caught and replaced with SigningKeyNotFoundException (as ExecutionException includes NetworkException):

    @Override
    public Jwk get(final String keyId) throws JwkException {
        try {
            String cacheKey = keyId == null ? NULL_KID_KEY : keyId;
            return cache.get(cacheKey, new Callable<Jwk>() {
                @Override
                public Jwk call() throws Exception {
                    return provider.get(keyId);
                }
            });
        } catch (ExecutionException e) {
            throw new SigningKeyNotFoundException("Failed to get key with kid " + keyId, e);
        }
    }
    

    This basically recreates the issue: #79.

    What was the expected behavior?

    NetworkException being thrown directly from: JwkProviderBuilder(URL(...)).cached(...).build().get(...) method when unable to connect to the url.

    Reproduction

    • Create cached provider for some urlPath of an offline server: val provider = JwkProviderBuilder(URL(urlPath)).cached(10, 1, TimeUnit.MINUTES).build()
    • Try to access the JWK for some keyId: provider.get(keyId)
    • Get the SigningKeyNotFoundException: Failed to get key with kid ****
    • Only able to trace exception.cause: java.util.concurrent.ExecutionException: com.auth0.jwk.NetworkException: Cannot obtain jwks from url ****

    Environment

    • Version of this library used: 0.21.2
    • Version of Java used: 11 (Kotlin 1.3.72)
    • Other modules/plugins/libraries that might be involved:
    • Any other relevant information you think would be useful:
    opened by adFrej 0
  • README: Fix provider.get code example

    README: Fix provider.get code example

    Changes

    Correcting the code example for provider.get in README.md by using a code block highlighted as Java, as was probably intended.

    I apologize if this PR is unnecessary and nitpicky, but I do believe that the change is benefitting to the first impression of the repo.

    Testing

    • [ ] This change adds test coverage
    • [ ] ~This change has been tested on the latest version of Java or why not~ This PR does not change code.

    Checklist

    opened by sivertschou 0
  • com.auth0.jwk.NetworkException: Cannot obtain jwks from url

    com.auth0.jwk.NetworkException: Cannot obtain jwks from url

    Hello, I'm encountering the issue "com.auth0.jwk.NetworkException: Cannot obtain jwks from url"

    I'm trying to get the jwks from microsoft. But encountering the below issue

    com.auth0.jwk.NetworkException: Cannot obtain jwks from url https://login.microsoftonline.com/common/discovery/v2.0/keys
            at com.auth0.jwk.UrlJwkProvider.getJwks(UrlJwkProvider.java:139) ~[jwks-rsa-0.21.2.jar:0.21.2]
            at com.auth0.jwk.UrlJwkProvider.getAll(UrlJwkProvider.java:145) ~[jwks-rsa-0.21.2.jar:0.21.2]
            at com.auth0.jwk.UrlJwkProvider.get(UrlJwkProvider.java:163) ~[jwks-rsa-0.21.2.jar:0.21.2]
    

    What was the expected behavior?

    Successfully obtain jwks from the specified url

    Reproduction

    --

    Environment

    • Version of this library used:0.21.2
    • Version of Java used:14
    • Other modules/plugins/libraries that might be involved:--
    • Any other relevant information you think would be useful:--
    opened by sivaraman-27 5
Releases(0.21.2)
Owner
Auth0
Auth0
Java JWT: JSON Web Token for Java and Android

Java JWT: JSON Web Token for Java and Android JJWT aims to be the easiest to use and understand library for creating and verifying JSON Web Tokens (JW

null 8.8k Dec 30, 2022
FastKV is an efficient and reliable key-value storage component written with Java.

FastKV 中文文档 FastKV is an efficient and reliable key-value storage component written with Java. It can be used on platforms with JVM environment, such

Billy Wei 274 Dec 28, 2022
Library to easily configure API Key authentication in (parts of) your Spring Boot Application

42 API Key Authentication A library to easily configure API Key authentication in (parts of) your Spring Boot Application. Features Easily configure A

null 2 Dec 8, 2021
A program that presses a key when you move your mouse to another monitor.

FollowMouse A program that presses a key when you move your mouse to another monitor. (useful for automatically changing scenes while livestreaming) F

Brime Live 7 Jul 31, 2022
JAP is an open source authentication middleware, it is highly decoupled from business code and has good modularity and flexiblity. Developers could integrate JAP into web applications effortlessly.

?? JAP 是什么? JAP 是一款开源的登录中间件,基于模块化设计,并且与业务高度解耦,使用起来非常灵活,开发者可以毫不费力地将 JAP 集

Fujie 140 Dec 1, 2022
一个轻量级Web蜜罐 - A Little Web Honeypot.🍯🍯🍯🐝🐝🐝

Loki Releases下载:https://github.com/TheKingOfDuck/Loki/releases/tag/0.1 更新日志 20210107 实现多端口监听 20210103 实现动态配置相关页面 20210124 实现配置指定端口指向指定模板文件 20210131 捕获

鸭王 150 Dec 5, 2022
Unofficial Clubhouse web app client. For personal use only. It's a personal open-source project and not affiliated with any company.

Purpose of this web app That's a personal project and not affiliated with any company. This is the web client app to make your Club House experience b

Sergei Ovchinnikov 45 Nov 15, 2022
Arkhota, a web brute forcer for Android.

Arkhota, a web brute forcer for Android What? Arkhota is a web (HTTP/S) brute forcer for Android. Why? A web brute forcer is always in a hacker's comp

ALW1EZ 55 Jan 6, 2023
Burp Extension for BFAC (Advanced Backup-File Artifacts Testing for Web-Applications)

BFAC - Burp Extension Burp Extension for BFAC (Advanced Backup-File Artifacts Testing for Web-Applications). What is BFAC - Burp Extension ? Backup fi

SEC-IT 18 Jul 16, 2022
🟪 TommyBox is a single-file executable that makes it possible to launch web apps on a desktop.

?? TommyBox About: TommyBox is a standalone executable container that makes it possible to launch static and dynamic web apps on a desktop by providin

null 19 May 28, 2022
2211-01-a-OMW2PCAFYB's Web Checkers Project

WC-2211-01-a-OMW2PCAFYB 2211-01-a-OMW2PCAFYB's Web Checkers Project This is the Web Checkers Project as established by SWEN-261 @ RIT Link to page: ht

Aidan Mellin 2 Oct 21, 2021
Anonymous chatting web app

Innogl This project is an anonymous web and video chat with strangers. Users can choose an online companion to discuss anything, find new friends or d

null 15 Oct 22, 2022
ByteSkriptQuery - A library for deploying ByteSkript as a backend web technology.

ByteSkriptQuery A language library for ByteSkript that allows it to be deployed as a backend web language. Not only does this allow the creation of ad

null 1 Jan 4, 2022
A Java program for web spidering.

JSpider JSpider is an advanced, multi-threaded Java library for crawling websites. It can be used as a command line program with all it's primary feat

Umar Abdul 2 Nov 5, 2022
Bridging IOTA's self-sovereign identities to existing "Web 2.0" OAuth solutions

IOTA Identity Provider Bridging IOTA's self-sovereign identities to existing "Web 2.0" OAuth solutions. NOTE: This plugin has NOT been audited or test

null 17 Nov 7, 2022
Convert Java to JSON. Convert JSON to Java. Pretty print JSON. Java JSON serializer.

json-io Perfect Java serialization to and from JSON format (available on Maven Central). To include in your project: <dependency> <groupId>com.cedar

John DeRegnaucourt 303 Dec 30, 2022
MapNeat is a JVM library written in Kotlin that provides an easy to use DSL (Domain Specific Language) for transforming JSON to JSON, XML to JSON, POJO to JSON in a declarative way.

MapNeat is a JVM library written in Kotlin that provides an easy to use DSL (Domain Specific Language) for transforming JSON to JSON, XML to JSON, POJ

Andrei Ciobanu 59 Sep 17, 2022
JSON Web Token implementation for Java according to RFC 7519. Easily create, parse and validate JSON Web Tokens using a fluent API.

JWT-Java JSON Web Token library for Java according to RFC 7519. Table of Contents What are JSON Web Tokens? Header Payload Signature Features Supporte

Bastiaan Jansen 6 Jul 10, 2022
An evolving set of open source web components for building mobile and desktop web applications in modern browsers.

Vaadin components Vaadin components is an evolving set of high-quality user interface web components commonly needed in modern mobile and desktop busi

Vaadin 519 Dec 31, 2022
JSON Web Token (JWT) implementation for Java with support for signatures (JWS), encryption (JWE) and web keys (JWK).

Nimbus JOSE+JWT Nimbus JOSE+JWT is a popular open source (Apache 2.0) Java library which implements the Javascript Object Signing and Encryption (JOSE

Connect2ID 35 Jul 1, 2022