Skip to content

Commit

Permalink
bugfix/skjermingsregister_proxy_401_merged (#3377)
Browse files Browse the repository at this point in the history
Azure-autentisering mot tjeneste skjermede-personer.
  • Loading branch information
rfc3092 authored Jan 12, 2024
1 parent 9dcb793 commit c2c83a4
Show file tree
Hide file tree
Showing 12 changed files with 272 additions and 76 deletions.
16 changes: 11 additions & 5 deletions proxies/skjermingsregister-proxy/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ sonarqube {
property "sonar.host.url", "https://sonarcloud.io"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.language", "java"
property "sonar.token", System.getenv("SONAR_TOKEN")
property "sonar.login", System.getenv("SONAR_TOKEN")
property "sonar.organization", "navikt"
property "sonar.project.monorepo.enabled", true
property "sonar.projectKey", "testnav-skjermingsregister-proxy"
Expand All @@ -50,25 +50,31 @@ repositories {
}

dependencies {

implementation 'no.nav.testnav.libs:data-transfer-objects'
implementation 'no.nav.testnav.libs:reactive-core'
implementation 'no.nav.testnav.libs:reactive-proxy'
implementation 'no.nav.testnav.libs:reactive-security'
implementation 'no.nav.testnav.libs:security-core'
implementation 'no.nav.testnav.libs:security-token-service'
implementation 'no.nav.testnav.libs:data-transfer-objects'

implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap' // TODO remove legacy bootstrap config
implementation 'org.springframework.cloud:spring-cloud-starter-vault-config'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'

implementation 'org.springframework.cloud:spring-cloud-starter-vault-config'

implementation 'net.logstash.logback:logstash-logback-encoder:7.4'
implementation 'org.hibernate.validator:hibernate-validator'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.cloud:spring-cloud-contract-wiremock'
testImplementation 'org.springframework.security:spring-security-test'

annotationProcessor 'org.projectlombok:lombok'
implementation 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
}

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
Expand Down
27 changes: 24 additions & 3 deletions proxies/skjermingsregister-proxy/config.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
apiVersion: "nais.io/v1alpha1"
kind: "Application"
---
apiVersion: nais.io/v1
kind: AzureAdApplication
metadata:
name: testnav-skjermingsregister-proxy-trygdeetaten
namespace: dolly
labels:
team: dolly
spec:
secretName: azure-trygdeetaten-testnav-skjermingsregister-proxy-trygdeetaten
secretKeyPrefix: "AZURE_TRYGDEETATEN"
tenant: trygdeetaten.no
---
apiVersion: nais.io/v1alpha1
kind: Application
metadata:
name: testnav-skjermingsregister-proxy
namespace: dolly
labels:
team: dolly
spec:
image: "{{image}}"
image: {{image}}
port: 8080
webproxy: true
tokenx:
enabled: true
azure:
application:
allowAllUsers: true
Expand All @@ -34,6 +49,10 @@ spec:
- application: app-1
namespace: plattformsikkerhet
cluster: dev-gcp
outbound:
rules:
- application: skjermede-personer
namespace: nom
liveness:
path: /internal/isAlive
initialDelay: 4
Expand All @@ -55,5 +74,7 @@ spec:
memory: 1024Mi
limits:
memory: 2048Mi
envFrom:
- secret: azure-trygdeetaten-testnav-skjermingsregister-proxy-trygdeetaten
ingresses:
- "https://testnav-skjermingsregister-proxy.dev-fss-pub.nais.io"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package no.nav.testnav.proxies.skjermingsregisterproxy;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import no.nav.testnav.libs.securitycore.domain.ServerProperties;

import static lombok.AccessLevel.PACKAGE;

@Configuration
@ConfigurationProperties(prefix = "consumers")
@NoArgsConstructor(access = PACKAGE)
@Getter
@Setter(PACKAGE)
public class Consumers {

private ServerProperties skjermingsregister;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package no.nav.testnav.proxies.skjermingsregisterproxy;

import io.micrometer.common.lang.NonNullApi;
import no.nav.testnav.libs.reactiveproxy.config.DevConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;
import org.springframework.vault.annotation.VaultPropertySource;
import org.springframework.vault.authentication.ClientAuthentication;
import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.config.AbstractVaultConfiguration;

import static io.micrometer.common.util.StringUtils.isBlank;

@Profile("local")
@Import(DevConfig.class)
@Configuration
@VaultPropertySource(value = "kv/preprod/fss/testnav-skjermingsregister-proxy/dev", ignoreSecretNotFound = false)
@NonNullApi
public class LocalVaultConfig extends AbstractVaultConfiguration {

static final String TOKEN_PROPERTY_NAME = "spring.cloud.vault.token";

@Override
public VaultEndpoint vaultEndpoint() {
return VaultEndpoint.create("vault.adeo.no", 443);
}

@Override
public ClientAuthentication clientAuthentication() {
if (System.getenv().containsKey("VAULT_TOKEN")) {
System.setProperty(TOKEN_PROPERTY_NAME, System.getenv("VAULT_TOKEN"));
}
var token = System.getProperty(TOKEN_PROPERTY_NAME);
if (isBlank(token)) {
throw new IllegalArgumentException("Påkrevet property '%s' er ikke satt.".formatted(TOKEN_PROPERTY_NAME));
}
return new TokenAuthentication(System.getProperty(TOKEN_PROPERTY_NAME));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package no.nav.testnav.proxies.skjermingsregisterproxy;

import no.nav.testnav.libs.reactiveproxy.config.SecurityConfig;
import no.nav.testnav.libs.reactiveproxy.filter.AddAuthenticationRequestGatewayFilterFactory;
import no.nav.testnav.libs.reactivesecurity.config.SecureOAuth2ServerToServerConfiguration;
import no.nav.testnav.libs.reactivesecurity.exchange.azuread.TrygdeetatenAzureAdTokenService;
import no.nav.testnav.libs.securitycore.domain.AccessToken;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Import({
SecureOAuth2ServerToServerConfiguration.class,
SecurityConfig.class
})
@Configuration
public class RouteLocatorConfig {

@Bean
public RouteLocator customRouteLocator(
RouteLocatorBuilder builder,
Consumers consumers,
GatewayFilter authenticationFilter
) {
return builder
.routes()
.route(spec -> spec
.path("/**")
.filters(f -> f.filter(authenticationFilter))
.uri(consumers.getSkjermingsregister().getUrl()))
.build();
}

@Bean
GatewayFilter getAuthenticationFilter(
TrygdeetatenAzureAdTokenService tokenService,
Consumers consumers
) {
return AddAuthenticationRequestGatewayFilterFactory
.bearerAuthenticationHeaderFilter(() -> tokenService
.exchange(consumers.getSkjermingsregister())
.map(AccessToken::getTokenValue));
}

}
Original file line number Diff line number Diff line change
@@ -1,51 +1,16 @@
package no.nav.testnav.proxies.skjermingsregisterproxy;

import no.nav.testnav.libs.reactivecore.config.CoreConfig;
import no.nav.testnav.libs.reactiveproxy.config.DevConfig;
import no.nav.testnav.libs.reactiveproxy.config.SecurityConfig;
import no.nav.testnav.libs.reactiveproxy.filter.AddAuthenticationRequestGatewayFilterFactory;
import no.nav.testnav.libs.securitytokenservice.StsOidcTokenService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

@Import({
CoreConfig.class,
DevConfig.class,
SecurityConfig.class
})
@SpringBootApplication
@Import(CoreConfig.class)
public class SkjermingsregisterProxyApplicationStarter {

public static void main(String[] args) {
SpringApplication.run(SkjermingsregisterProxyApplicationStarter.class, args);
}

@Bean
public StsOidcTokenService stsOidcTokenService(
@Value("${sts.token.provider.url}") String url,
@Value("${sts.token.provider.username}") String username,
@Value("${sts.token.provider.password}") String password) {

return new StsOidcTokenService(url, username, password);
}

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, StsOidcTokenService stsOidcTokenService) {

var addAuthenticationHeaderFilter = AddAuthenticationRequestGatewayFilterFactory
.bearerAuthenticationHeaderFilter(stsOidcTokenService::getToken);

return builder.routes()
.route(spec -> spec
.path("/**")
.filters(filterSpec -> filterSpec
.filter(addAuthenticationHeaderFilter))
.uri("http://skjermede-personer.nom.svc.nais.local/"))
.build();
}

}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ spring:
jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys
accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id}
tokenx:
issuer-uri: https://tokenx.dev-gcp.nav.cloud.nais.io
issuer-uri: https://tokenx.dev-gcp.nav.cloud.nais.io
jwk-set-uri: https://tokenx.dev-gcp.nav.cloud.nais.io/jwks
accepted-audience: ${TOKEN_X_CLIENT_ID}
cloud:
gateway:
httpclient:
response-timeout: 30s

sts:
token:
provider:
url: https://security-token-service.dev.adeo.no/rest/v1/sts/token
username: ${STS_TOKEN_PROVIDER_USERNAME}
password: ${STS_TOKEN_PROVIDER_PASSWORD}
consumers:
skjermingsregister:
name: skjermede-personer
namespace: nom
url: https://skjermede-personer.dev.adeo.no
cluster: dev-fss
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</root>
</springProfile>

<springProfile name="dev">
<springProfile name="local">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
Expand All @@ -37,4 +37,5 @@
</springProfile>

<logger level="TRACE" name="no.nav.testnav.libs.reactivecore.filter.RequestLogger" />

</configuration>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package no.nav.testnav.proxies.skjermingsregisterproxy;

import org.junit.jupiter.api.Test;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.vault.authentication.TokenAuthentication;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;

@ActiveProfiles("test")
class LocalVaultConfigTest {

@Test
void missingSystemPropertyShouldFail() {
assertThatThrownBy(new LocalVaultConfig()::clientAuthentication)
.isInstanceOf(IllegalArgumentException.class);
}

@Test
void environmentPropertyShouldTakePrecedenceOverSystemProperty() {
try {
System.setProperty(LocalVaultConfig.TOKEN_PROPERTY_NAME, "<some-token-here>");
assertThat(new LocalVaultConfig())
.isNotNull()
.satisfies(
config -> assertThat(config.clientAuthentication())
.isNotNull()
.isInstanceOf(TokenAuthentication.class)
);
} finally {
System.clearProperty(LocalVaultConfig.TOKEN_PROPERTY_NAME);
}
}

@Test
void vaultEndpointShouldBeKnown() {
assertThat(new LocalVaultConfig().vaultEndpoint())
.isNotNull()
.satisfies(endpoint -> {
assertThat(endpoint.getHost()).isEqualTo("vault.adeo.no");
assertThat(endpoint.getPort()).isEqualTo(443);
});
}

}
Loading

0 comments on commit c2c83a4

Please sign in to comment.