Skip to content

Commit

Permalink
add keyCloakUrl request before cache update
Browse files Browse the repository at this point in the history
  • Loading branch information
max402 committed May 2, 2024
1 parent bbcdca2 commit 9d2b300
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

public class AuthServerTestable extends LoggingAuthServer {

public AuthServerTestable(String name, String issUrl, String jwksUrl, int refreshIntervalSeconds) {
super(name, issUrl, jwksUrl, refreshIntervalSeconds);
public AuthServerTestable(String name, String issUrl, String jwksUrl, int refreshIntervalSeconds, String keyCloakUrl) {
super(name, issUrl, jwksUrl, refreshIntervalSeconds, keyCloakUrl);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ private AuthServer mapFromProperties(AuthServerConfigurationProperties.AuthServe
properties.getName(),
properties.getIssUrl(),
properties.getJwksUrl(),
properties.getRefreshIntervalSeconds()
properties.getRefreshIntervalSeconds(),
properties.getKeyCloakUrl()
);
}
}
2 changes: 2 additions & 0 deletions sts-example/src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ sts:
- name: local keycloak
iss-url : http://localhost:8080/auth/realms/moped
jwks-url: http://localhost:8080/auth/realms/moped/protocol/openid-connect/certs
key-cloak-url: http://localhost:8080/auth/realms/moped
- name: secret-server
iss-url : http://localhost:8885
jwks-url: http://localhost:8885/pop
key-cloak-url: http://localhost:8085/realms/moped
resource-servers:
- audience: sts
jwks-url: http://localhost:8888/pop
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.adorsys.sts.token.authentication;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
Expand All @@ -22,42 +24,13 @@ public void setAuthservers(List<AuthServerProperties> authservers) {
this.authservers = authservers;
}

@Getter
@Setter
public static class AuthServerProperties {
private String name;
private String issUrl;
private String jwksUrl;
private Integer refreshIntervalSeconds = 600;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getIssUrl() {
return issUrl;
}

public void setIssUrl(String issUrl) {
this.issUrl = issUrl;
}

public String getJwksUrl() {
return jwksUrl;
}

public void setJwksUrl(String jwksUrl) {
this.jwksUrl = jwksUrl;
}

public Integer getRefreshIntervalSeconds() {
return refreshIntervalSeconds;
}

public void setRefreshIntervalSeconds(Integer refreshIntervalSeconds) {
this.refreshIntervalSeconds = refreshIntervalSeconds;
}
private String keyCloakUrl;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ private AuthServer mapFromProperties(AuthServerConfigurationProperties.AuthServe
properties.getName(),
properties.getIssUrl(),
properties.getJwksUrl(),
properties.getRefreshIntervalSeconds()
properties.getRefreshIntervalSeconds(),
properties.getKeyCloakUrl()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package de.adorsys.sts.token.authentication;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.jwk.JWK;
import de.adorsys.sts.tokenauth.AuthServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class LoggingAuthServer extends AuthServer {

public LoggingAuthServer(String name, String issUrl, String jwksUrl, int refreshIntervalSeconds) {
super(name, issUrl, jwksUrl, refreshIntervalSeconds);
public LoggingAuthServer(String name, String issUrl, String jwksUrl, int refreshIntervalSeconds, String keyCloakUrl) {
super(name, issUrl, jwksUrl, refreshIntervalSeconds, keyCloakUrl);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.adorsys.sts.tokenauth;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.KeySourceException;
import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.jwk.source.JWKSourceBuilder;
Expand All @@ -10,7 +11,11 @@
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.net.URI;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.security.Key;
import java.util.Date;
import java.util.List;
Expand All @@ -25,24 +30,26 @@ public class AuthServer {
private final String issUrl;
private final String jwksUrl;
private final int refreshIntervalSeconds;
private final String keyCloakUrl;

@Setter
JWKSource<SecurityContext> jwkSource;

final ConcurrentHashMap<String, JWK> jwkCache = new ConcurrentHashMap<>();
long lastCacheUpdate = 0;

public AuthServer(String name, String issUrl, String jwksUrl) {
this(name, issUrl, jwksUrl, 600);
public AuthServer(String name, String issUrl, String jwksUrl, String keyCloakUrl) {
this(name, issUrl, jwksUrl, 600, keyCloakUrl);
}

@SneakyThrows
public AuthServer(String name, String issUrl, String jwksUrl, int refreshIntervalSeconds) {
public AuthServer(String name, String issUrl, String jwksUrl, int refreshIntervalSeconds, String keyCloakUrl) {
super();
this.name = name;
this.issUrl = issUrl;
this.jwksUrl = jwksUrl;
this.refreshIntervalSeconds = refreshIntervalSeconds;
this.keyCloakUrl = keyCloakUrl;

jwkSource = JWKSourceBuilder.create(new URL(this.jwksUrl)).build();
}
Expand All @@ -51,6 +58,12 @@ private void updateJwkCache() throws JsonWebKeyRetrievalException {
log.debug("Thread entering updateJwkCache: " + Thread.currentThread().getId());

try {
if (keyCloakUrl != null) {
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().GET().uri(URI.create(keyCloakUrl)).build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.info("Checking keycloak availability: " + response.statusCode());
}

List<JWK> jwks = jwkSource.get(new JWKSelector(new JWKMatcher.Builder().build()), null);
onJsonWebKeySetRetrieved(jwks);
Expand All @@ -61,6 +74,8 @@ private void updateJwkCache() throws JsonWebKeyRetrievalException {
jwkCache.put(jwk.getKeyID(), jwk);
}
lastCacheUpdate = new Date().getTime();
} catch (KeySourceException e) {
log.warn("couldn't update jwk cache: ", e);
} catch (Exception e) {
throw new JsonWebKeyRetrievalException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
import java.security.interfaces.RSAPublicKey;
import java.util.Collections;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

Expand All @@ -29,7 +32,7 @@ class AuthServerTest {

@BeforeEach
void setUp() throws Exception {
authServer = new AuthServer("TestServer", "https://example.com/iss", "https://example.com/jwks", 10);
authServer = new AuthServer("TestServer", "https://example.com/iss", "https://example.com/jwks", 10, null);
mockRemoteJWKSet = Mockito.mock(RemoteJWKSet.class);
JWK jwk = new RSAKey.Builder(new Base64URL("n"), new Base64URL("e")).keyID("testKey").build();
when(mockRemoteJWKSet.get(any(JWKSelector.class), any(SecurityContext.class))).thenReturn(Collections.singletonList(jwk));
Expand All @@ -52,7 +55,7 @@ void testCacheUpdateAfterInterval() throws Exception {
RSAKey rsaKey = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic()).keyID("testKey").build();

// Configure your AuthServer instance
AuthServer authServer = new AuthServer("TestServer", "https://example.com/iss", "https://example.com/jwks");
AuthServer authServer = new AuthServer("TestServer", "https://example.com/iss", "https://example.com/jwks", null);
authServer.setJwkSource(mockJwkSource); // Inject the mock

// Mock the JWKSource and configure it to return the mock RSAKey
Expand Down Expand Up @@ -82,7 +85,7 @@ void testValidKeyRetrieval() throws Exception {
Mockito.when(mockJwkSource.get(any(), any())).thenReturn(Collections.singletonList(rsaKey));

// Inject the mock JWKSource into your AuthServer
AuthServer authServer = new AuthServer("TestServer", "https://example.com/iss", "https://example.com/jwks");
AuthServer authServer = new AuthServer("TestServer", "https://example.com/iss", "https://example.com/jwks", null);
// Assuming you have a method to set the JWKSource
authServer.setJwkSource(mockJwkSource);
// Now you can test your method
Expand Down

0 comments on commit 9d2b300

Please sign in to comment.