Skip to content

Commit 5ae29be

Browse files
client interceptor and matcher using OAuth2AccessTokenService (#318)
* client interceptor that exchanges a token using the {@link OAuth2AccessTokenService} and sets Authorization header to this new token * configuration is retrieved through a configurable matcher implementing `ClientConfigurationPropertiesMatcher` * if no configuration is found this interceptor is NOOP. Must be registered by the applications themselves, * no automatic bean registration. Co-authored-by: Jan-Olav Eide <jan-olav.eide@nav.no>
1 parent 4d05dca commit 5ae29be

File tree

3 files changed

+90
-22
lines changed

3 files changed

+90
-22
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package no.nav.security.token.support.client.spring.oauth2;
2+
3+
import java.util.Optional;
4+
5+
import org.springframework.http.HttpRequest;
6+
7+
import no.nav.security.token.support.client.core.ClientProperties;
8+
import no.nav.security.token.support.client.spring.ClientConfigurationProperties;
9+
10+
/**
11+
*
12+
* Default implementation that matcher host in request URL with the registration
13+
* name. Override for other strategies. Will typically be used with
14+
* {@link OAuth2ClientRequestInterceptor}. Must be registered by the
15+
* applications themselves, no automatic bean registration
16+
*
17+
*/
18+
public interface ClientConfigurationPropertiesMatcher {
19+
default Optional<ClientProperties> findProperties(ClientConfigurationProperties properties, HttpRequest request) {
20+
return Optional.ofNullable(properties.getRegistration().get(request.getURI().getHost()));
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package no.nav.security.token.support.client.spring.oauth2;
2+
3+
import java.io.IOException;
4+
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
import org.springframework.http.HttpRequest;
8+
import org.springframework.http.client.ClientHttpRequestExecution;
9+
import org.springframework.http.client.ClientHttpRequestInterceptor;
10+
import org.springframework.http.client.ClientHttpResponse;
11+
12+
import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenService;
13+
import no.nav.security.token.support.client.spring.ClientConfigurationProperties;
14+
15+
/**
16+
*
17+
* Interceptor that exchanges a token using the {@link OAuth2AccessTokenService}
18+
* and sets Authorization header to this new token, where the aud claim is set
19+
* to the destination app. The configuration fo this app is retrieved through a
20+
* configurable matcher implementing
21+
* {@link ClientConfigurationPropertiesMatcher}. If no configuration is found,
22+
* this interceptor is NOOP. Must be registered by the applications themselves,
23+
* no automatic bean registration.
24+
*
25+
*/
26+
public class OAuth2ClientRequestInterceptor implements ClientHttpRequestInterceptor {
27+
28+
private static final Logger LOG = LoggerFactory.getLogger(OAuth2ClientRequestInterceptor.class);
29+
private final ClientConfigurationProperties properties;
30+
private final OAuth2AccessTokenService service;
31+
private final ClientConfigurationPropertiesMatcher matcher;
32+
33+
public OAuth2ClientRequestInterceptor(ClientConfigurationProperties properties,
34+
OAuth2AccessTokenService service, ClientConfigurationPropertiesMatcher matcher) {
35+
this.properties = properties;
36+
this.service = service;
37+
this.matcher = matcher;
38+
}
39+
40+
@Override
41+
public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution execution) throws IOException {
42+
matcher.findProperties(properties, req)
43+
.ifPresentOrElse(config -> req.getHeaders().setBearerAuth(service.getAccessToken(config).getAccessToken()),
44+
() -> LOG.info("Ingen konfig for {}", req.getURI()));
45+
46+
return execution.execute(req, body);
47+
}
48+
49+
@Override
50+
public String toString() {
51+
return getClass().getSimpleName() + " [properties=" + properties + ", service=" + service + ", matcher=" + matcher + "]";
52+
}
53+
54+
}

token-client-spring/src/test/java/no/nav/security/token/support/client/spring/oauth2/ClientConfigurationPropertiesTest.java

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
package no.nav.security.token.support.client.spring.oauth2;
22

3-
import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
4-
import no.nav.security.token.support.client.core.ClientAuthenticationProperties;
5-
import no.nav.security.token.support.client.core.ClientProperties;
6-
import no.nav.security.token.support.client.core.oauth2.OnBehalfOfGrantRequest;
7-
import no.nav.security.token.support.client.spring.ClientConfigurationProperties;
8-
import no.nav.security.token.support.core.context.TokenValidationContextHolder;
9-
import org.junit.jupiter.api.BeforeEach;
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.util.Map;
6+
107
import org.junit.jupiter.api.Test;
11-
import org.mockito.MockitoAnnotations;
128
import org.springframework.beans.factory.annotation.Autowired;
139
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
1410
import org.springframework.boot.test.context.SpringBootTest;
1511
import org.springframework.boot.test.mock.mockito.MockBean;
1612
import org.springframework.test.context.ActiveProfiles;
1713

18-
import java.util.Map;
14+
import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
1915

20-
import static org.assertj.core.api.Assertions.assertThat;
16+
import no.nav.security.token.support.client.core.ClientAuthenticationProperties;
17+
import no.nav.security.token.support.client.core.ClientProperties;
18+
import no.nav.security.token.support.client.core.oauth2.OnBehalfOfGrantRequest;
19+
import no.nav.security.token.support.client.spring.ClientConfigurationProperties;
20+
import no.nav.security.token.support.core.context.TokenValidationContextHolder;
2121

22-
@SpringBootTest(classes = {OAuth2ClientConfiguration.class, RestTemplateAutoConfiguration.class})
22+
@SpringBootTest(classes = { OAuth2ClientConfiguration.class, RestTemplateAutoConfiguration.class })
2323
@ActiveProfiles("test")
2424
class ClientConfigurationPropertiesTest {
2525

@@ -29,17 +29,11 @@ class ClientConfigurationPropertiesTest {
2929
@Autowired
3030
private ClientConfigurationProperties clientConfigurationProperties;
3131

32-
@BeforeEach
33-
void before() {
34-
MockitoAnnotations.initMocks(this);
35-
}
36-
3732
@Test
3833
void testClientConfigIsValid() {
3934
assertThat(clientConfigurationProperties).isNotNull();
4035
assertThat(clientConfigurationProperties.getRegistration()).isNotNull();
41-
ClientProperties clientProperties =
42-
clientConfigurationProperties.getRegistration().values().stream().findFirst().orElse(null);
36+
ClientProperties clientProperties = clientConfigurationProperties.getRegistration().values().stream().findFirst().orElse(null);
4337
assertThat(clientProperties).isNotNull();
4438
ClientAuthenticationProperties auth = clientProperties.getAuthentication();
4539
assertThat(auth).isNotNull();
@@ -56,8 +50,7 @@ void testTokenExchangeProperties() {
5650
assertThat(clientConfigurationProperties).isNotNull();
5751
assertThat(clientConfigurationProperties.getRegistration()).isNotNull();
5852
System.out.println(clientConfigurationProperties);
59-
ClientProperties clientProperties =
60-
clientConfigurationProperties.getRegistration().get("example1-token-exchange1");
53+
ClientProperties clientProperties = clientConfigurationProperties.getRegistration().get("example1-token-exchange1");
6154

6255
assertThat(clientProperties).isNotNull();
6356
assertThat(clientProperties.getTokenExchange().getAudience()).isNotBlank();
@@ -67,8 +60,7 @@ void testTokenExchangeProperties() {
6760
void testClientConfigWithClientAuthMethodAsPrivateKeyJwt() {
6861
assertThat(clientConfigurationProperties).isNotNull();
6962
assertThat(clientConfigurationProperties.getRegistration()).isNotNull();
70-
ClientProperties clientProperties =
71-
clientConfigurationProperties.getRegistration().get("example1-clientcredentials3");
63+
ClientProperties clientProperties = clientConfigurationProperties.getRegistration().get("example1-clientcredentials3");
7264
assertThat(clientProperties).isNotNull();
7365
ClientAuthenticationProperties auth = clientProperties.getAuthentication();
7466
assertThat(auth).isNotNull();

0 commit comments

Comments
 (0)