44import lombok .RequiredArgsConstructor ;
55import lombok .Setter ;
66import lombok .extern .slf4j .Slf4j ;
7+ import org .springframework .beans .factory .annotation .Value ;
78import org .springframework .boot .autoconfigure .condition .ConditionalOnProperty ;
89import org .springframework .boot .context .properties .ConfigurationProperties ;
910import org .springframework .context .annotation .Bean ;
1011import org .springframework .context .annotation .Configuration ;
1112import org .springframework .core .convert .converter .Converter ;
1213import org .springframework .http .HttpMethod ;
13- import org .springframework .security .config .Customizer ;
14+ import org .springframework .security .authentication .AuthenticationManager ;
15+ import org .springframework .security .authentication .ProviderManager ;
1416import org .springframework .security .config .annotation .method .configuration .EnableMethodSecurity ;
1517import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
1618import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
1719import org .springframework .security .config .annotation .web .configurers .AbstractHttpConfigurer ;
1820import org .springframework .security .config .http .SessionCreationPolicy ;
1921import org .springframework .security .core .GrantedAuthority ;
2022import org .springframework .security .oauth2 .jwt .Jwt ;
23+ import org .springframework .security .oauth2 .jwt .NimbusJwtDecoder ;
2124import org .springframework .security .oauth2 .server .resource .authentication .JwtAuthenticationConverter ;
25+ import org .springframework .security .oauth2 .server .resource .authentication .JwtAuthenticationProvider ;
26+ import org .springframework .security .oauth2 .server .resource .authentication .JwtIssuerAuthenticationManagerResolver ;
2227import org .springframework .security .web .SecurityFilterChain ;
23- import org .springframework .security .web .util .matcher .AntPathRequestMatcher ;
2428
2529import java .util .Collection ;
2630import java .util .Collections ;
31+ import java .util .HashMap ;
2732import java .util .List ;
2833import java .util .Map ;
2934
@@ -43,29 +48,36 @@ public class OIDCSecurityConfig {
4348 private final RoleConfiguration roleConfiguration ;
4449 private final SecurityTokenProperties inseeSecurityTokenProperties ;
4550
51+ @ Value ("${fr.insee.genesis.security.resourceserver.jwt.issuer-uri}" )
52+ String issuerUri ;
53+
54+ @ Value ("${fr.insee.genesis.security.resourceserver.dmz.jwt.issuer-uri}" )
55+ String issuerUriDmz ;
56+
4657 @ Bean
47- public SecurityFilterChain filterChain (HttpSecurity http ) throws Exception {
58+ public SecurityFilterChain filterChain (HttpSecurity http , JwtIssuerAuthenticationManagerResolver authenticationManagerResolver ) throws Exception {
4859 http
4960 .csrf (AbstractHttpConfigurer ::disable )
50- .sessionManagement (sess -> sess .sessionCreationPolicy (SessionCreationPolicy .STATELESS ));
51- for (var pattern : whitelistMatchers ) {
52- http .authorizeHttpRequests (authorize ->
53- authorize
54- .requestMatchers (AntPathRequestMatcher .antMatcher (pattern )).permitAll ()
55- );
56- }
57- http
58- .authorizeHttpRequests (configure -> configure
61+ .sessionManagement (sess -> sess .sessionCreationPolicy (SessionCreationPolicy .STATELESS ))
62+ .authorizeHttpRequests (authorize -> authorize
63+ // Whitelisted paths sans auth
64+ .requestMatchers (whitelistMatchers ).permitAll ()
65+
66+ // Secured reader-access paths
5967 .requestMatchers (HttpMethod .GET ,"/questionnaires/**" ).hasRole (String .valueOf (ApplicationRole .READER ))
6068 .requestMatchers (HttpMethod .GET ,"/modes/**" ).hasRole (String .valueOf (ApplicationRole .READER ))
6169 .requestMatchers (HttpMethod .GET ,"/interrogations/**" ).hasRole (String .valueOf (ApplicationRole .READER ))
6270 .requestMatchers (HttpMethod .GET ,"/campaigns/**" ).hasRole (String .valueOf (ApplicationRole .READER ))
71+
72+ //All others require authentication
6373 .anyRequest ().authenticated ()
6474 )
65- .oauth2ResourceServer (oauth2 -> oauth2 .jwt (Customizer .withDefaults ()));
75+ .oauth2ResourceServer (
76+ oauth2 -> oauth2 .authenticationManagerResolver (authenticationManagerResolver ));
6677 return http .build ();
6778 }
6879
80+
6981 @ Bean
7082 JwtAuthenticationConverter jwtAuthenticationConverter () {
7183 JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter ();
@@ -75,6 +87,26 @@ JwtAuthenticationConverter jwtAuthenticationConverter() {
7587 }
7688
7789
90+
91+ @ Bean
92+ public JwtIssuerAuthenticationManagerResolver authenticationManagerResolver () {
93+ final List <String > issuers = List .of (issuerUri ,issuerUriDmz );
94+ Map <String , AuthenticationManager > authenticationManagers = new HashMap <>();
95+
96+ for (String issuer : issuers ) {
97+ NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder
98+ .withJwkSetUri (issuer + "/protocol/openid-connect/certs" )
99+ .build ();
100+
101+ JwtAuthenticationProvider provider = new JwtAuthenticationProvider (jwtDecoder );
102+ provider .setJwtAuthenticationConverter (jwtAuthenticationConverter ());
103+
104+ AuthenticationManager manager = new ProviderManager (provider );
105+ authenticationManagers .put (issuer , manager );
106+ }
107+ return new JwtIssuerAuthenticationManagerResolver (authenticationManagers ::get );
108+ }
109+
78110 Converter <Jwt , Collection <GrantedAuthority >> jwtGrantedAuthoritiesConverter () {
79111 return new Converter <Jwt , Collection <GrantedAuthority >>() {
80112 @ Override
0 commit comments