private String refreshCache() { try { URL openIdUrl = new URL(this.url); HashMap<String, String> openIdConf = mapper.readValue(openIdUrl, new TypeReference<HashMap<String, Object>>(){}); URL keysUrl = new URL(openIdConf.get("jwks_uri")); this.lastUpdated = System.currentTimeMillis(); this.cacheKeys = new UrlJwkProvider(keysUrl); return IOUtils.toString(keysUrl); } catch (IOException e) { String errorDescription = String.format("Failed to load openID config: %s", e.getMessage()); LOGGER.log(Level.WARNING, errorDescription); } return null; }
@Override public Jwk get(String keyId) throws JwkException { final List<Jwk> jwks = getAll(); if (keyId == null && jwks.size() == 1) { return jwks.get(0); } if (keyId != null) { for (Jwk jwk : jwks) { if (keyId.equals(jwk.getId())) { return jwk; } } } throw new SigningKeyNotFoundException("No key found in " + url.toString() + " with kid " + keyId, null); } }
private List<Jwk> getAll() throws SigningKeyNotFoundException { List<Jwk> jwks = Lists.newArrayList(); @SuppressWarnings("unchecked") final List<Map<String, Object>> keys = (List<Map<String, Object>>) getJwks().get("keys"); if (keys == null || keys.isEmpty()) { throw new SigningKeyNotFoundException("No keys found in " + url.toString(), null); } try { for (Map<String, Object> values : keys) { jwks.add(Jwk.fromValues(values)); } } catch (IllegalArgumentException e) { throw new SigningKeyNotFoundException("Failed to parse jwk from json", e); } return jwks; }
@Test public void shouldReturnWithoutIdWhenSingleJwk() throws Exception { UrlJwkProvider provider = new UrlJwkProvider(getClass().getResource("/jwks-single-no-kid.json")); assertThat(provider.get(null), notNullValue()); UrlJwkProvider provider2 = new UrlJwkProvider(getClass().getResource("/jwks-single.json")); assertThat(provider2.get(null), notNullValue()); }
/** * Creates a provider that loads from the given domain's well-known directory. * <br><br> It can be a url link 'https://samples.auth0.com' or just a domain 'samples.auth0.com'. * If the protocol (http or https) is not provided then https is used by default. * The default jwks path "/.well-known/jwks.json" is appended to the given string domain. * <br><br> For example, when the domain is "samples.auth0.com" * the jwks url that will be used is "https://samples.auth0.com/.well-known/jwks.json" * <br><br> Use {@link #UrlJwkProvider(URL)} if you need to pass a full URL. * * @param domain where jwks is published */ public UrlJwkProvider(String domain) { this(urlForDomain(domain)); }
@Test public void shouldFailToLoadByDifferentIdWhenSingleJwk() throws Exception { expectedException.expect(SigningKeyNotFoundException.class); UrlJwkProvider provider = new UrlJwkProvider(getClass().getResource("/jwks-single-no-kid.json")); provider.get("wrong-kid"); }
private static URL buildJwkUrl(String domain) { if (domain == null) { throw new IllegalStateException("Cannot build provider without domain"); } return urlForDomain(domain); }
private String refreshCache() { try { URL openIdUrl = new URL(this.url); HashMap<String, String> openIdConf = this.mapper.readValue(openIdUrl, new TypeReference<HashMap<String, Object>>(){}); URL keysUrl = new URL(openIdConf.get("jwks_uri")); this.lastUpdated = System.currentTimeMillis(); this.cacheKeys = new UrlJwkProvider(keysUrl); return IOUtils.toString(keysUrl); } catch (IOException e) { String errorDescription = String.format("Failed to load openID config: %s", e.getMessage()); LOGGER.log(Level.WARNING, errorDescription); } return null; }
@Test public void shouldFailToLoadSingleWithoutIdWhenMultipleJwk() throws Exception { expectedException.expect(SigningKeyNotFoundException.class); UrlJwkProvider provider = new UrlJwkProvider(getClass().getResource("/jwks.json")); provider.get(null); }
@Inject public KeycloakJwkProvider(KeycloakSettings keycloakSettings) throws MalformedURLException { final String jwksUrl = keycloakSettings.get().get(KeycloakConstants.JWKS_ENDPOINT_SETTING); if (jwksUrl == null) { throw new ConfigurationException("Jwks endpoint url not found in keycloak settings"); } this.jwkProvider = new GuavaCachedJwkProvider(new UrlJwkProvider(new URL(jwksUrl))); }
@Test public void shouldFailToLoadSingleWhenJsonIsInvalid() throws Exception { expectedException.expect(SigningKeyNotFoundException.class); UrlJwkProvider provider = new UrlJwkProvider(getClass().getResource("/invalid-jwks.json")); provider.get(KID); }
public Oauth2Client(TokensStore tokenStore, Oauth2Properties oauthProperties) throws Exception { this.tokenStore = tokenStore; this.oauthProperties = oauthProperties; RestTemplate rt = new RestTemplate(); rt.getInterceptors().add(createClientAuthInterceptor(oauthProperties)); this.oauthRestTemplate = rt; this.jwkProvider = new GuavaCachedJwkProvider( traceJwkLookupsOf(new UrlJwkProvider(new URL(oauthProperties.getJwksEndpoint())))); }
@Test public void shouldReturnByIdWhenSingleJwk() throws Exception { UrlJwkProvider provider = new UrlJwkProvider(getClass().getResource("/jwks-single.json")); assertThat(provider.get(KID), notNullValue()); }
/** * Creates a {@link JwkProvider} * * @return a newly created {@link JwkProvider} */ public JwkProvider build() { JwkProvider urlProvider = new UrlJwkProvider(url); if (this.rateLimited) { urlProvider = new RateLimitedJwkProvider(urlProvider, bucket); } if (this.cached) { urlProvider = new GuavaCachedJwkProvider(urlProvider, cacheSize, expiresIn, expiresUnit); } return urlProvider; } }
@Test public void shouldReturnSingleJwkById() throws Exception { UrlJwkProvider provider = new UrlJwkProvider(getClass().getResource("/jwks.json")); assertThat(provider.get(KID), notNullValue()); }
@Test public void shouldBuildCorrectHttpsUrlOnDomainWithHttpsAndSlash() { String httpsDomain = "https://samples.auth0.com"; String httpsDomainWithSlash = httpsDomain + "/"; String actualJwksUrl = new UrlJwkProvider(httpsDomainWithSlash).url.toString(); assertThat(actualJwksUrl, equalTo(httpsDomain + WELL_KNOWN_JWKS_PATH)); }
@Test public void shouldFailToLoadSingleWhenUrlHasNothing() throws Exception { expectedException.expect(SigningKeyNotFoundException.class); UrlJwkProvider provider = new UrlJwkProvider(new URL("file:///not_found.file")); provider.get(KID); }
@Test public void shouldBuildCorrectHttpsUrlOnDomainWithHttps() { String httpsDomain = "https://samples.auth0.com"; String actualJwksUrl = new UrlJwkProvider(httpsDomain).url.toString(); assertThat(actualJwksUrl, equalTo(httpsDomain + WELL_KNOWN_JWKS_PATH)); }
@Test public void shouldFailToLoadSingleWhenKeysIsEmpty() throws Exception { expectedException.expect(SigningKeyNotFoundException.class); UrlJwkProvider provider = new UrlJwkProvider(getClass().getResource("/empty-jwks.json")); provider.get(KID); }
@Test public void shouldBuildCorrectHttpUrlOnDomainWithHttp() { String httpDomain = "http://samples.auth0.com"; String actualJwksUrl = new UrlJwkProvider(httpDomain).url.toString(); assertThat(actualJwksUrl, equalTo(httpDomain + WELL_KNOWN_JWKS_PATH)); }