JAVA-29306 Upgrade spring-security-web-boot-3 (#15622)

Co-authored-by: timis1 <noreplay@yahoo.com>
This commit is contained in:
timis1 2024-01-15 01:32:31 +02:00 committed by GitHub
parent 797f1e1737
commit eb6e485b58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 65 additions and 101 deletions

View File

@ -11,8 +11,9 @@
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>spring-security-modules</artifactId> <artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-3</relativePath>
</parent> </parent>
<dependencies> <dependencies>
@ -30,7 +31,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>de.flapdoodle.embed</groupId> <groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId> <artifactId>de.flapdoodle.embed.mongo.spring30x</artifactId>
<version>${de.flapdoodle.emeded.mongo.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
@ -65,11 +67,22 @@
<artifactId>spring-security-test</artifactId> <artifactId>spring-security-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
<bootstrap.version>5.1.1</bootstrap.version> <bootstrap.version>5.1.1</bootstrap.version>
<jquery.version>3.6.0</jquery.version> <jquery.version>3.6.0</jquery.version>
<start-class>com.baeldung.cors.basicauth.SpringBootSecurityApplication</start-class>
<de.flapdoodle.emeded.mongo.version>4.11.0</de.flapdoodle.emeded.mongo.version>
</properties> </properties>
</project> </project>

View File

@ -3,14 +3,14 @@ package com.baeldung.cachecontrol.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableMethodSecurity
public class SpringSecurityConfig { public class SpringSecurityConfig {
@Bean @Bean

View File

@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;

View File

@ -2,7 +2,9 @@ package com.baeldung.contentsecuritypolicy;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.header.writers.StaticHeadersWriter; import org.springframework.security.web.header.writers.StaticHeadersWriter;
@ -12,17 +14,14 @@ public class ContentSecurityPolicySecurityConfiguration {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf() http.csrf(AbstractHttpConfigurer::disable)
.disable() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers("/**").permitAll())
.authorizeRequests() .headers(httpSecurityHeadersConfigurer ->
.antMatchers("/**") httpSecurityHeadersConfigurer
.permitAll() .addHeaderWriter(new StaticHeadersWriter("Report-To", REPORT_TO))
.and() .xssProtection(Customizer.withDefaults())
.headers() .contentSecurityPolicy(contentSecurityPolicyConfig ->
.addHeaderWriter(new StaticHeadersWriter("Report-To", REPORT_TO)) contentSecurityPolicyConfig.policyDirectives("form-action 'self'; report-uri /report; report-to csp-violation-report")));
.xssProtection()
.and()
.contentSecurityPolicy("form-action 'self'; report-uri /report; report-to csp-violation-report");
return http.build(); return http.build();
} }
} }

View File

@ -1,21 +1,21 @@
package com.baeldung.cors.basicauth.config; package com.baeldung.cors.basicauth.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity @EnableWebSecurity
public class WebSecurityConfig { public class WebSecurityConfig {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests() http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.anyRequest().authenticated())
.anyRequest() .httpBasic(Customizer.withDefaults());
.authenticated() http.cors(Customizer.withDefaults()); // disable this line to reproduce the CORS 401
.and()
.httpBasic();
http.cors(); // disable this line to reproduce the CORS 401
return http.build(); return http.build();
} }
} }

View File

@ -4,7 +4,9 @@ import java.util.Arrays;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.firewall.HttpFirewall; import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.HttpStatusRequestRejectedHandler; import org.springframework.security.web.firewall.HttpStatusRequestRejectedHandler;
@ -16,15 +18,10 @@ public class HttpFirewallConfiguration {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf() http.csrf(AbstractHttpConfigurer::disable)
.disable() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.authorizeRequests() authorizationManagerRequestMatcherRegistry.requestMatchers("/error").permitAll().anyRequest().authenticated())
.antMatchers("/error") .httpBasic(Customizer.withDefaults());
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
return http.build(); return http.build();
} }

View File

@ -20,9 +20,8 @@ public class SecurityConfig {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests() http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.antMatchers("/**") authorizationManagerRequestMatcherRegistry.requestMatchers("/**").permitAll());
.permitAll();
return http.build(); return http.build();
} }
} }

View File

@ -4,11 +4,10 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import com.baeldung.mongoauth.config.MongoConfig;
import com.baeldung.mongoauth.config.SecurityConfig; import com.baeldung.mongoauth.config.SecurityConfig;
@SpringBootApplication @SpringBootApplication
@Import({ SecurityConfig.class, MongoConfig.class }) @Import({ SecurityConfig.class })
public class MongoAuthApplication { public class MongoAuthApplication {
public static void main(String... args) { public static void main(String... args) {

View File

@ -1,40 +0,0 @@
package com.baeldung.mongoauth.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.util.SocketUtils;
import com.mongodb.client.MongoClients;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.ImmutableMongodConfig;
import de.flapdoodle.embed.mongo.config.MongodConfig;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
@Configuration
public class MongoConfig {
private static final String CONNECTION_STRING = "mongodb://%s:%d";
private static final String HOST = "localhost";
@Bean
public MongoTemplate mongoTemplate() throws Exception {
int randomPort = SocketUtils.findAvailableTcpPort();
ImmutableMongodConfig mongoDbConfig = MongodConfig.builder()
.version(Version.Main.PRODUCTION)
.net(new Net(HOST, randomPort, Network.localhostIsIPv6()))
.build();
MongodStarter starter = MongodStarter.getDefaultInstance();
MongodExecutable mongodExecutable = starter.prepare(mongoDbConfig);
mongodExecutable.start();
return new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, HOST, randomPort)), "mongo_auth");
}
}

View File

@ -3,10 +3,12 @@ package com.baeldung.mongoauth.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@ -38,18 +40,11 @@ public class SecurityConfig {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf() http.csrf(AbstractHttpConfigurer::disable)
.disable() .authorizeHttpRequests(Customizer.withDefaults())
.authorizeRequests() .httpBasic(Customizer.withDefaults())
.and() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.anyRequest().permitAll())
.httpBasic() .sessionManagement(httpSecuritySessionManagementConfigurer -> httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
.and()
.authorizeRequests()
.anyRequest()
.permitAll()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build(); return http.build();
} }

View File

@ -1,6 +1,6 @@
package com.baeldung.mongoauth.controller; package com.baeldung.mongoauth.controller;
import javax.annotation.security.RolesAllowed; import jakarta.annotation.security.RolesAllowed;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;

View File

@ -30,10 +30,7 @@ public class MongoAuthUserDetailService implements UserDetailsService {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>(); Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
user.getAuthorities() user.getAuthorities()
.forEach(role -> { .forEach(role -> grantedAuthorities.add(new SimpleGrantedAuthority(role.getRole().getName())));
grantedAuthorities.add(new SimpleGrantedAuthority(role.getRole()
.getName()));
});
return new User(user.getUsername(), user.getPassword(), grantedAuthorities); return new User(user.getUsername(), user.getPassword(), grantedAuthorities);
} }

View File

@ -10,9 +10,8 @@ public class SecurityConfig {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests() http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.antMatchers("/**") authorizationManagerRequestMatcherRegistry.requestMatchers("/**").permitAll());
.permitAll();
return http.build(); return http.build();
} }
} }

View File

@ -1 +1,3 @@
spring.mongodb.embedded.version=4.4.9 de.flapdoodle.mongodb.embedded.version=7.0.2
spring.data.mongodb.database=mongo_auth
spring.data.mongodb.port=27018

View File

@ -4,7 +4,7 @@ import io.restassured.http.ContentType;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import static io.restassured.RestAssured.given; import static io.restassured.RestAssured.given;

View File

@ -12,7 +12,7 @@ import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.util.Collection; import java.util.Collection;

View File

@ -5,6 +5,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
@ -15,8 +16,11 @@ import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import de.flapdoodle.embed.mongo.spring.autoconfigure.EmbeddedMongoAutoConfiguration;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(classes = { SpringBootSecurityApplication.class }) @SpringBootTest(classes = { SpringBootSecurityApplication.class })
@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class})
public class ResourceControllerUnitTest { public class ResourceControllerUnitTest {
private MockMvc mockMvc; private MockMvc mockMvc;

View File

@ -85,7 +85,7 @@ class UserApiLiveTest {
void givenCredentials_whenHttpGet_thenReturnAllUsers() throws Exception { void givenCredentials_whenHttpGet_thenReturnAllUsers() throws Exception {
// @formatter:off // @formatter:off
MvcResult result=mockMvc MvcResult result=mockMvc
.perform(get("/api/v1/users/") .perform(get("/api/v1/users")
.contentType("application/json")).andReturn(); .contentType("application/json")).andReturn();
// @formatter:on // @formatter:on
assertEquals(HttpStatus.OK.value(), result.getResponse().getStatus()); assertEquals(HttpStatus.OK.value(), result.getResponse().getStatus());

View File

@ -133,7 +133,7 @@ class UserApiUnitTest {
when(userService.findAll()).thenReturn(UserTestUtility.createUsers()); when(userService.findAll()).thenReturn(UserTestUtility.createUsers());
MvcResult result = mockMvc MvcResult result = mockMvc
.perform(get("/api/v1/users/") .perform(get("/api/v1/users")
.accept("application/json")) .accept("application/json"))
.andDo(print()) .andDo(print())
.andReturn(); .andReturn();