Skip to content

Commit 95e9bcf

Browse files
authored
feature/noop-userinfo (#3721)
* Added new autoconfiguration for noop userinfo beans. * Provider configurations now only uses issuer-uri. * Added a noop ReactiveClientRegistrationRepository used in test profile to avoid mocking.
1 parent 77665f6 commit 95e9bcf

File tree

10 files changed

+141
-20
lines changed

10 files changed

+141
-20
lines changed

apps/dolly-frontend/src/main/resources/application-local.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ spring:
2222
client-secret: ${AZURE_APP_CLIENT_SECRET}
2323
provider:
2424
aad:
25-
authorization-uri: ${AAD_ISSUER_URI}/oauth2/v2.0/authorize
26-
token-uri: ${AAD_ISSUER_URI}/oauth2/v2.0/token
27-
jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys
25+
issuer-uri: ${sm\://azure-openid-config-issuer}
2826

2927
consumers:
3028
testnav-altinn3-tilgang-service:

apps/endringsmelding-frontend/src/main/java/no/nav/testnav/apps/endringsmeldingfrontend/EndringsmeldingFrontendApplicationStarter.java

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
2020
import org.springframework.context.annotation.Bean;
2121
import org.springframework.context.annotation.Import;
22+
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
2223

2324
import java.util.function.Function;
2425

@@ -28,6 +29,7 @@
2829
FrontendConfig.class
2930
})
3031
@SpringBootApplication
32+
@EnableWebFluxSecurity
3133
@RequiredArgsConstructor
3234
public class EndringsmeldingFrontendApplicationStarter {
3335

apps/endringsmelding-frontend/src/main/java/no/nav/testnav/apps/endringsmeldingfrontend/config/SecurityConfig.java

+15-10
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,29 @@
22

33
import org.springframework.context.annotation.Bean;
44
import org.springframework.context.annotation.Configuration;
5-
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
65
import org.springframework.security.config.web.server.ServerHttpSecurity;
76
import org.springframework.security.web.server.SecurityWebFilterChain;
87

8+
import static org.springframework.security.config.Customizer.withDefaults;
99

1010
@Configuration
11-
@EnableWebFluxSecurity
12-
public class SecurityConfig {
11+
class SecurityConfig {
1312

1413
@Bean
15-
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
16-
return http.cors(ServerHttpSecurity.CorsSpec::disable)
14+
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
15+
return http
16+
.cors(ServerHttpSecurity.CorsSpec::disable)
1717
.csrf(ServerHttpSecurity.CsrfSpec::disable)
18-
.authorizeExchange(authorizeExchangeSpec -> authorizeExchangeSpec
19-
.pathMatchers("/internal/isReady", "/internal/isAlive", "/internal/metrics").permitAll()
20-
.anyExchange().authenticated())
21-
.oauth2Login(oAuth2LoginSpec -> {
22-
})
18+
.authorizeExchange(spec -> spec
19+
.pathMatchers(
20+
"/internal/isReady",
21+
"/internal/isAlive",
22+
"/internal/metrics")
23+
.permitAll()
24+
.anyExchange()
25+
.authenticated())
26+
.oauth2Login(withDefaults())
2327
.build();
2428
}
29+
2530
}

apps/endringsmelding-frontend/src/main/resources/application.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ spring:
1818
scope: openid, ${AZURE_APP_CLIENT_ID}/.default
1919
provider:
2020
aad:
21-
authorization-uri: ${AAD_ISSUER_URI}/oauth2/v2.0/authorize
22-
token-uri: ${AAD_ISSUER_URI}/oauth2/v2.0/token
23-
jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys
21+
issuer-uri: ${AZURE_OPENID_CONFIG_ISSUER}
2422

2523
consumers:
2624
endringsmelding-service:

apps/faste-data-frontend/src/main/resources/application.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ spring:
2121
scope: openid, ${AZURE_APP_CLIENT_ID}/.default
2222
provider:
2323
aad:
24-
authorization-uri: ${AAD_ISSUER_URI}/oauth2/v2.0/authorize
25-
token-uri: ${AAD_ISSUER_URI}/oauth2/v2.0/token
26-
jwk-set-uri: ${AAD_ISSUER_URI}/discovery/v2.0/keys
24+
issuer-uri: ${AZURE_OPENID_CONFIG_ISSUER}
2725

2826
consumers:
2927
testnorge-profil-api:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package no.nav.testnav.libs.securitycore.oauth2.client.userinfo;
2+
3+
import org.springframework.security.core.GrantedAuthority;
4+
import org.springframework.security.core.authority.SimpleGrantedAuthority;
5+
import org.springframework.security.oauth2.client.oidc.userinfo.OidcReactiveOAuth2UserService;
6+
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
7+
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
8+
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
9+
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
10+
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
11+
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
12+
import org.springframework.util.StringUtils;
13+
import reactor.core.publisher.Mono;
14+
15+
import java.util.LinkedHashSet;
16+
17+
class NoopOidcReactiveOAuth2UserService extends OidcReactiveOAuth2UserService {
18+
19+
/**
20+
* Stripped from {@code org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequestUtils#getUser(OidcUserRequest, OidcUserInfo)}.
21+
*
22+
* @param userRequest OIDC user request.
23+
* @return OIDC user.
24+
*/
25+
private static OidcUser getUser(OidcUserRequest userRequest) {
26+
27+
var authorities = new LinkedHashSet<GrantedAuthority>();
28+
authorities.add(new OidcUserAuthority(userRequest.getIdToken(), null));
29+
userRequest
30+
.getAccessToken()
31+
.getScopes()
32+
.forEach(scope -> authorities.add(new SimpleGrantedAuthority("SCOPE_" + scope)));
33+
var providerDetails = userRequest
34+
.getClientRegistration()
35+
.getProviderDetails();
36+
var userNameAttributeName = providerDetails
37+
.getUserInfoEndpoint()
38+
.getUserNameAttributeName();
39+
if (StringUtils.hasText(userNameAttributeName)) {
40+
return new DefaultOidcUser(authorities, userRequest.getIdToken(), null, userNameAttributeName);
41+
}
42+
return new DefaultOidcUser(authorities, userRequest.getIdToken(), (OidcUserInfo) null);
43+
44+
}
45+
46+
@Override
47+
public Mono<OidcUser> loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
48+
return Mono.just(getUser(userRequest));
49+
}
50+
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package no.nav.testnav.libs.securitycore.oauth2.client.userinfo;
2+
3+
import org.springframework.security.oauth2.client.registration.ClientRegistration;
4+
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
5+
import reactor.core.publisher.Mono;
6+
7+
class NoopReactiveClientRegistrationRepository implements ReactiveClientRegistrationRepository {
8+
9+
@Override
10+
public Mono<ClientRegistration> findByRegistrationId(String registrationId) {
11+
return Mono.empty();
12+
}
13+
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package no.nav.testnav.libs.securitycore.oauth2.client.userinfo;
2+
3+
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
4+
import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService;
5+
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
6+
import org.springframework.security.oauth2.core.user.OAuth2User;
7+
import reactor.core.publisher.Mono;
8+
9+
class NoopReactiveOAuth2UserService implements ReactiveOAuth2UserService<OAuth2UserRequest, OAuth2User> {
10+
11+
@Override
12+
public Mono<OAuth2User> loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
13+
return Mono.empty();
14+
}
15+
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package no.nav.testnav.libs.securitycore.oauth2.client.userinfo;
2+
3+
import org.springframework.boot.autoconfigure.AutoConfiguration;
4+
import org.springframework.context.annotation.Bean;
5+
import org.springframework.context.annotation.Profile;
6+
import org.springframework.security.oauth2.client.oidc.userinfo.OidcReactiveOAuth2UserService;
7+
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
8+
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
9+
import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService;
10+
import org.springframework.security.oauth2.core.user.OAuth2User;
11+
12+
@AutoConfiguration
13+
public class NoopReactiveOauth2AutoConfiguration {
14+
15+
@Bean
16+
ReactiveOAuth2UserService<OAuth2UserRequest, OAuth2User> reactiveOAuth2UserService() {
17+
return new NoopReactiveOAuth2UserService();
18+
}
19+
20+
@Bean
21+
OidcReactiveOAuth2UserService oidcReactiveOAuth2UserService() {
22+
return new NoopOidcReactiveOAuth2UserService();
23+
}
24+
25+
/**
26+
* When testing, just use an empty repository so we don't trigger the full behaviour of
27+
* {@code InMemoryReactiveClientRegistrationRepository} - which is not needed for tests.
28+
* @return An instance of {@code NoopReactiveClientRegistrationRepository}.
29+
* @see org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository
30+
* @see no.nav.testnav.libs.securitycore.oauth2.client.userinfo.NoopReactiveClientRegistrationRepository
31+
*/
32+
@Bean
33+
@Profile("test")
34+
ReactiveClientRegistrationRepository reactiveClientRegistrationRepositoryForTesting() {
35+
return new NoopReactiveClientRegistrationRepository();
36+
}
37+
38+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
no.nav.testnav.libs.securitycore.domain.azuread.ClientCredentialAutoConfiguration
1+
no.nav.testnav.libs.securitycore.domain.azuread.ClientCredentialAutoConfiguration
2+
no.nav.testnav.libs.securitycore.oauth2.client.userinfo.NoopReactiveOauth2AutoConfiguration

0 commit comments

Comments
 (0)