JAVA-29305 Upgrade spring-security-web-boot-2 (#15510)

* JAVA-29305 Upgrade spring-security-web-boot-2

* JAVA-29305 Formatting code

---------

Co-authored-by: timis1 <noreplay@yahoo.com>
This commit is contained in:
timis1 2024-01-04 17:43:24 +02:00 committed by GitHub
parent c159de77db
commit 906faa4fa6
17 changed files with 179 additions and 167 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>
@ -34,7 +35,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.thymeleaf.extras</groupId> <groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId> <artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -81,11 +82,6 @@
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId> <artifactId>spring-security-core</artifactId>
</dependency> </dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId> <artifactId>spring-security-config</artifactId>
@ -100,6 +96,15 @@
<version>${ehcache-core.version}</version> <version>${ehcache-core.version}</version>
<type>jar</type> <type>jar</type>
</dependency> </dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -7,8 +7,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
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.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler; import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
@ -27,27 +29,21 @@ public class MvcConfiguration {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.httpBasic() http.httpBasic(Customizer.withDefaults())
.and() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.authorizeRequests() authorizationManagerRequestMatcherRegistry.requestMatchers(HttpMethod.GET, "/user/**").hasRole("USER"))
.antMatchers(HttpMethod.GET, "/user/**") .logout(httpSecurityLogoutConfigurer ->
.hasRole("USER") httpSecurityLogoutConfigurer.logoutUrl("/user/logout")
.and() .addLogoutHandler(logoutHandler)
.logout() .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)).permitAll())
.logoutUrl("/user/logout") .securityContext(httpSecuritySecurityContextConfigurer -> httpSecuritySecurityContextConfigurer.requireExplicitSave(false))
.addLogoutHandler(logoutHandler) .csrf(AbstractHttpConfigurer::disable)
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)) .formLogin(AbstractHttpConfigurer::disable);
.permitAll()
.and()
.csrf()
.disable()
.formLogin()
.disable();
return http.build(); return http.build();
} }
@Bean @Bean
public JdbcUserDetailsManager jdbcUserDetailsManager() throws Exception { public JdbcUserDetailsManager jdbcUserDetailsManager() {
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource); JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
jdbcUserDetailsManager.setUsersByUsernameQuery("select login, password, true from users where login=?"); jdbcUserDetailsManager.setUsersByUsernameQuery("select login, password, true from users where login=?");
jdbcUserDetailsManager.setAuthoritiesByUsernameQuery("select login, role from users where login=?"); jdbcUserDetailsManager.setAuthoritiesByUsernameQuery("select login, role from users where login=?");

View File

@ -3,8 +3,8 @@ package com.baeldung.customlogouthandler.services;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import javax.persistence.EntityManager; import jakarta.persistence.EntityManager;
import javax.persistence.PersistenceContext; import jakarta.persistence.PersistenceContext;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

View File

@ -1,6 +1,6 @@
package com.baeldung.customlogouthandler.user; package com.baeldung.customlogouthandler.user;
import javax.persistence.*; import jakarta.persistence.*;
@Entity @Entity
@Table(name = "users") @Table(name = "users")

View File

@ -1,7 +1,7 @@
package com.baeldung.customlogouthandler.web; package com.baeldung.customlogouthandler.web;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler; import org.springframework.security.web.authentication.logout.LogoutHandler;

View File

@ -3,10 +3,13 @@ package com.baeldung.jdbcauthentication.h2.config;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
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.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.AbstractAuthenticationFilterConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
@ -16,19 +19,15 @@ public class SecurityConfiguration {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests() httpSecurity.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.antMatchers("/h2-console/**") authorizationManagerRequestMatcherRegistry
.permitAll() .requestMatchers(PathRequest.toH2Console()).permitAll().anyRequest().authenticated())
.anyRequest() .formLogin(AbstractAuthenticationFilterConfigurer::permitAll);
.authenticated()
.and() httpSecurity.csrf(httpSecurityCsrfConfigurer -> httpSecurityCsrfConfigurer.ignoringRequestMatchers(PathRequest.toH2Console()));
.formLogin()
.permitAll(); httpSecurity.headers(httpSecurityHeadersConfigurer ->
httpSecurity.csrf() httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin));
.ignoringAntMatchers("/h2-console/**");
httpSecurity.headers()
.frameOptions()
.sameOrigin();
return httpSecurity.build(); return httpSecurity.build();
} }

View File

@ -1,17 +1,17 @@
package com.baeldung.loginredirect; package com.baeldung.loginredirect;
import org.apache.http.HttpStatus; import org.apache.hc.core5.http.HttpStatus;
import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean; import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain; import jakarta.servlet.FilterChain;
import javax.servlet.ServletException; import jakarta.servlet.ServletException;
import javax.servlet.ServletRequest; import jakarta.servlet.ServletRequest;
import javax.servlet.ServletResponse; import jakarta.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
class LoginPageFilter extends GenericFilterBean { class LoginPageFilter extends GenericFilterBean {

View File

@ -1,9 +1,9 @@
package com.baeldung.loginredirect; package com.baeldung.loginredirect;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.apache.http.HttpStatus; import org.apache.hc.core5.http.HttpStatus;
import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;

View File

@ -4,6 +4,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
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.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@ -16,6 +17,8 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
@EnableWebSecurity @EnableWebSecurity
class LoginRedirectSecurityConfig { class LoginRedirectSecurityConfig {
private static final String LOGIN_USER = "/loginUser";
@Bean @Bean
public InMemoryUserDetailsManager userDetailsService() { public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withUsername("user") UserDetails user = User.withUsername("user")
@ -28,26 +31,20 @@ class LoginRedirectSecurityConfig {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.addFilterAfter(new LoginPageFilter(), UsernamePasswordAuthenticationFilter.class) http.addFilterAfter(new LoginPageFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.antMatchers("/loginUser") authorizationManagerRequestMatcherRegistry.requestMatchers(LOGIN_USER).permitAll()
.permitAll() .requestMatchers("/user*").hasRole("USER"))
.antMatchers("/user*") .formLogin(httpSecurityFormLoginConfigurer ->
.hasRole("USER") httpSecurityFormLoginConfigurer.loginPage(LOGIN_USER)
.and() .loginProcessingUrl("/user_login")
.formLogin() .failureUrl("/loginUser?error=loginError")
.loginPage("/loginUser") .defaultSuccessUrl("/userMainPage").permitAll())
.loginProcessingUrl("/user_login") .logout(httpSecurityLogoutConfigurer ->
.failureUrl("/loginUser?error=loginError") httpSecurityLogoutConfigurer
.defaultSuccessUrl("/userMainPage") .logoutUrl("/user_logout")
.permitAll() .logoutSuccessUrl(LOGIN_USER)
.and() .deleteCookies("JSESSIONID"))
.logout() .csrf(AbstractHttpConfigurer::disable);
.logoutUrl("/user_logout")
.logoutSuccessUrl("/loginUser")
.deleteCookies("JSESSIONID")
.and()
.csrf()
.disable();
return http.build(); return http.build();
} }

View File

@ -1,15 +1,21 @@
package com.baeldung.multipleauthproviders; package com.baeldung.multipleauthproviders;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
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.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.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
@Configuration
@EnableWebSecurity @EnableWebSecurity
public class MultipleAuthProvidersSecurityConfig { public class MultipleAuthProvidersSecurityConfig {
@ -28,14 +34,14 @@ public class MultipleAuthProvidersSecurityConfig {
} }
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authManager) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authManager, HandlerMappingIntrospector introspector) throws Exception {
http.httpBasic() MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
.and() http.httpBasic(Customizer.withDefaults())
.authorizeRequests() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.antMatchers("/api/**") authorizationManagerRequestMatcherRegistry
.authenticated() .requestMatchers(PathRequest.toH2Console()).authenticated()
.and() .requestMatchers(mvcMatcherBuilder.pattern("/api/**")).authenticated())
.authenticationManager(authManager); .authenticationManager(authManager);
return http.build(); return http.build();
} }

View File

@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
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.core.userdetails.User; import org.springframework.security.core.userdetails.User;
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;
@ -14,14 +15,16 @@ import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
public class MultipleEntryPointsSecurityConfig { public class MultipleEntryPointsSecurityConfig {
@Bean @Bean
public UserDetailsService userDetailsService() throws Exception { public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build());
manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build());
@ -38,11 +41,14 @@ public class MultipleEntryPointsSecurityConfig {
public static class App1ConfigurationAdapter { public static class App1ConfigurationAdapter {
@Bean @Bean
public SecurityFilterChain filterChainApp1(HttpSecurity http) throws Exception { public SecurityFilterChain filterChainApp1(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
http.antMatcher("/admin/**") MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
.authorizeRequests().anyRequest().hasRole("ADMIN") http.securityMatcher("/admin/**")
.and().httpBasic().authenticationEntryPoint(authenticationEntryPoint()) .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.and().exceptionHandling().accessDeniedPage("/403"); authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/admin/**")).hasRole("ADMIN"))
.httpBasic(httpSecurityHttpBasicConfigurer -> httpSecurityHttpBasicConfigurer.authenticationEntryPoint(authenticationEntryPoint()))
.exceptionHandling(httpSecurityExceptionHandlingConfigurer ->
httpSecurityExceptionHandlingConfigurer.accessDeniedPage("/403"));
return http.build(); return http.build();
} }
@ -59,18 +65,24 @@ public class MultipleEntryPointsSecurityConfig {
public static class App2ConfigurationAdapter { public static class App2ConfigurationAdapter {
@Bean @Bean
public SecurityFilterChain filterChainApp2(HttpSecurity http) throws Exception { public SecurityFilterChain filterChainApp2(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
http.antMatcher("/user/**") MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
.authorizeRequests().anyRequest().hasRole("USER") http.securityMatcher("/user/**")
.and().formLogin().loginProcessingUrl("/user/login") .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
.failureUrl("/userLogin?error=loginError").defaultSuccessUrl("/user/myUserPage") authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/user/**")).hasRole("USER"))
.and().logout().logoutUrl("/user/logout").logoutSuccessUrl("/multipleHttpLinks") .formLogin(httpSecurityFormLoginConfigurer ->
.deleteCookies("JSESSIONID") httpSecurityFormLoginConfigurer.loginProcessingUrl("/user/login")
.and().exceptionHandling() .failureUrl("/userLogin?error=loginError")
.defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPointWithWarning(), new AntPathRequestMatcher("/user/private/**")) .defaultSuccessUrl("/user/myUserPage"))
.defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPoint(), new AntPathRequestMatcher("/user/general/**")) .logout(httpSecurityLogoutConfigurer ->
.accessDeniedPage("/403") httpSecurityLogoutConfigurer.logoutUrl("/user/logout")
.and().csrf().disable(); .logoutSuccessUrl("/multipleHttpLinks")
.deleteCookies("JSESSIONID"))
.exceptionHandling(httpSecurityExceptionHandlingConfigurer ->
httpSecurityExceptionHandlingConfigurer.defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPointWithWarning(), new AntPathRequestMatcher("/user/private/**"))
.defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPoint(), new AntPathRequestMatcher("/user/general/**"))
.accessDeniedPage("/403"))
.csrf(AbstractHttpConfigurer::disable);
return http.build(); return http.build();
} }
@ -90,11 +102,10 @@ public class MultipleEntryPointsSecurityConfig {
public static class App3ConfigurationAdapter { public static class App3ConfigurationAdapter {
@Bean @Bean
public SecurityFilterChain filterChainApp3(HttpSecurity http) throws Exception { public SecurityFilterChain filterChainApp3(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
http.antMatcher("/guest/**") MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
.authorizeRequests() http.securityMatcher("/guest/**")
.anyRequest() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/guest/**")).permitAll());
.permitAll();
return http.build(); return http.build();
} }
} }

View File

@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
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.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
@ -12,13 +13,15 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
public class MultipleLoginSecurityConfig { public class MultipleLoginSecurityConfig {
@Bean @Bean
public UserDetailsService userDetailsService() throws Exception { public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build());
manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build());
@ -44,30 +47,24 @@ public class MultipleLoginSecurityConfig {
} }
@Bean @Bean
public SecurityFilterChain filterChainApp1(HttpSecurity http) throws Exception { public SecurityFilterChain filterChainApp1(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
http.antMatcher("/admin*") MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
.authorizeRequests() http.securityMatcher("/admin*")
.anyRequest() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/admin*")).hasRole("ADMIN"))
.hasRole("ADMIN")
// log in // log in
.and() .formLogin(httpSecurityFormLoginConfigurer ->
.formLogin() httpSecurityFormLoginConfigurer.loginPage("/loginAdmin")
.loginPage("/loginAdmin") .loginProcessingUrl("/admin_login")
.loginProcessingUrl("/admin_login") .failureUrl("/loginAdmin?error=loginError")
.failureUrl("/loginAdmin?error=loginError") .defaultSuccessUrl("/adminPage"))
.defaultSuccessUrl("/adminPage")
// logout // logout
.and() .logout(httpSecurityLogoutConfigurer ->
.logout() httpSecurityLogoutConfigurer.logoutUrl("/admin_logout")
.logoutUrl("/admin_logout") .logoutSuccessUrl("/protectedLinks")
.logoutSuccessUrl("/protectedLinks") .deleteCookies("JSESSIONID"))
.deleteCookies("JSESSIONID") .exceptionHandling(httpSecurityExceptionHandlingConfigurer ->
.and() httpSecurityExceptionHandlingConfigurer.accessDeniedPage("/403"))
.exceptionHandling() .csrf(AbstractHttpConfigurer::disable);
.accessDeniedPage("/403")
.and()
.csrf()
.disable();
return http.build(); return http.build();
} }
@ -87,30 +84,24 @@ public class MultipleLoginSecurityConfig {
} }
@Bean @Bean
public SecurityFilterChain filterChainApp2(HttpSecurity http) throws Exception { public SecurityFilterChain filterChainApp2(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
http.antMatcher("/user*") MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
.authorizeRequests() http.securityMatcher("/user*")
.anyRequest() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/user*")).hasRole("USER"))
.hasRole("USER")
// log in // log in
.and() .formLogin(httpSecurityFormLoginConfigurer ->
.formLogin() httpSecurityFormLoginConfigurer.loginPage("/loginUser")
.loginPage("/loginUser") .loginProcessingUrl("/user_login")
.loginProcessingUrl("/user_login") .failureUrl("/loginUser?error=loginError")
.failureUrl("/loginUser?error=loginError") .defaultSuccessUrl("/userPage"))
.defaultSuccessUrl("/userPage")
// logout // logout
.and() .logout(httpSecurityLogoutConfigurer ->
.logout() httpSecurityLogoutConfigurer.logoutUrl("/user_logout")
.logoutUrl("/user_logout") .logoutSuccessUrl("/protectedLinks")
.logoutSuccessUrl("/protectedLinks") .deleteCookies("JSESSIONID"))
.deleteCookies("JSESSIONID") .exceptionHandling(httpSecurityExceptionHandlingConfigurer ->
.and() httpSecurityExceptionHandlingConfigurer.accessDeniedPage("/403"))
.exceptionHandling() .csrf(AbstractHttpConfigurer::disable);
.accessDeniedPage("/403")
.and()
.csrf()
.disable();
return http.build(); return http.build();
} }
} }

View File

@ -1,18 +1,21 @@
package com.baeldung.ssl; package com.baeldung.ssl;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
@Configuration
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfig { public class SecurityConfig {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
http.authorizeRequests() MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
.antMatchers("/**") http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/**")).permitAll());
.permitAll();
return http.build(); return http.build();
} }
} }

View File

@ -7,7 +7,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
@ -21,7 +21,8 @@ import com.baeldung.customlogouthandler.services.UserCache;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = { CustomLogoutApplication.class }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(classes = { CustomLogoutApplication.class }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@SqlGroup({ @Sql(value = "classpath:customlogouthandler/before.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD), @Sql(value = "classpath:customlogouthandler/after.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) }) @SqlGroup({ @Sql(value = "classpath:customlogouthandler/before.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD),
@Sql(value = "classpath:customlogouthandler/after.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) })
@TestPropertySource(locations="classpath:customlogouthandler/application.properties") @TestPropertySource(locations="classpath:customlogouthandler/application.properties")
class CustomLogoutHandlerIntegrationTest { class CustomLogoutHandlerIntegrationTest {
@ -37,7 +38,7 @@ class CustomLogoutHandlerIntegrationTest {
@Test @Test
public void whenLogin_thenUseUserCache() { public void whenLogin_thenUseUserCache() {
// User cache should be empty on start // User cache should be empty on start
assertThat(userCache.size()).isEqualTo(0); assertThat(userCache.size()).isZero();
// Request using first login // Request using first login
ResponseEntity<String> response = restTemplate.withBasicAuth("user", "pass") ResponseEntity<String> response = restTemplate.withBasicAuth("user", "pass")
@ -66,7 +67,7 @@ class CustomLogoutHandlerIntegrationTest {
@Test @Test
public void whenLogout_thenCacheIsEmpty() { public void whenLogout_thenCacheIsEmpty() {
// User cache should be empty on start // User cache should be empty on start
assertThat(userCache.size()).isEqualTo(0); assertThat(userCache.size()).isZero();
// Request using first login // Request using first login
ResponseEntity<String> response = restTemplate.withBasicAuth("user", "pass") ResponseEntity<String> response = restTemplate.withBasicAuth("user", "pass")
@ -89,7 +90,7 @@ class CustomLogoutHandlerIntegrationTest {
// User cache must be empty now // User cache must be empty now
// this is the reaction on custom logout filter execution // this is the reaction on custom logout filter execution
assertThat(userCache.size()).isEqualTo(0); assertThat(userCache.size()).isZero();
// Assert unauthorized request // Assert unauthorized request
response = restTemplate.exchange(getLanguageUrl(), HttpMethod.GET, new HttpEntity<String>(requestHeaders), String.class); response = restTemplate.exchange(getLanguageUrl(), HttpMethod.GET, new HttpEntity<String>(requestHeaders), String.class);

View File

@ -17,10 +17,10 @@ public class UserControllerLiveTest {
private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal";
@Test @Test
public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { public void givenExisting_whenRequestPrincipal_thenRetrieveData() {
SessionFilter filter = new SessionFilter(); SessionFilter filter = new SessionFilter();
given().auth() given().auth()
.form("user", "pass", new FormAuthConfig("/login", "username", "password").withCsrfFieldName("_csrf")) .form("user", "pass", new FormAuthConfig("/login", "username", "password").withAdditionalField("_csrf"))
.and() .and()
.filter(filter) .filter(filter)
.when() .when()

View File

@ -1,8 +1,10 @@
package com.baeldung.web; package com.baeldung.web;
import org.apache.http.client.HttpClient; import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.http.impl.client.HttpClients; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContextBuilder;
import com.baeldung.ssl.HttpsEnabledApplication; import com.baeldung.ssl.HttpsEnabledApplication;
import org.junit.Test; import org.junit.Test;
@ -47,8 +49,9 @@ public class HttpsApplicationIntegrationTest {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()) SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray())
.build(); .build();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext); SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(socketFactory).build();
HttpClient httpClient = HttpClients.custom() HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory) .setConnectionManager(connectionManager)
.build(); .build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory); return new RestTemplate(factory);

View File

@ -24,7 +24,7 @@ public class MultipleAuthProvidersApplicationIntegrationTest {
public void givenMemUsers_whenGetPingWithValidUser_thenOk() { public void givenMemUsers_whenGetPingWithValidUser_thenOk() {
ResponseEntity<String> result = makeRestCallToGetPing("memuser", "pass"); ResponseEntity<String> result = makeRestCallToGetPing("memuser", "pass");
assertThat(result.getStatusCodeValue()).isEqualTo(200); assertThat(result.getStatusCode().value()).isEqualTo(200);
assertThat(result.getBody()).isEqualTo("OK"); assertThat(result.getBody()).isEqualTo("OK");
} }
@ -32,7 +32,7 @@ public class MultipleAuthProvidersApplicationIntegrationTest {
public void givenExternalUsers_whenGetPingWithValidUser_thenOK() { public void givenExternalUsers_whenGetPingWithValidUser_thenOK() {
ResponseEntity<String> result = makeRestCallToGetPing("externaluser", "pass"); ResponseEntity<String> result = makeRestCallToGetPing("externaluser", "pass");
assertThat(result.getStatusCodeValue()).isEqualTo(200); assertThat(result.getStatusCode().value()).isEqualTo(200);
assertThat(result.getBody()).isEqualTo("OK"); assertThat(result.getBody()).isEqualTo("OK");
} }
@ -40,14 +40,14 @@ public class MultipleAuthProvidersApplicationIntegrationTest {
public void givenAuthProviders_whenGetPingWithNoCred_then401() { public void givenAuthProviders_whenGetPingWithNoCred_then401() {
ResponseEntity<String> result = makeRestCallToGetPing(); ResponseEntity<String> result = makeRestCallToGetPing();
assertThat(result.getStatusCodeValue()).isEqualTo(401); assertThat(result.getStatusCode().value()).isEqualTo(401);
} }
@Test @Test
public void givenAuthProviders_whenGetPingWithBadCred_then401() { public void givenAuthProviders_whenGetPingWithBadCred_then401() {
ResponseEntity<String> result = makeRestCallToGetPing("user", "bad_password"); ResponseEntity<String> result = makeRestCallToGetPing("user", "bad_password");
assertThat(result.getStatusCodeValue()).isEqualTo(401); assertThat(result.getStatusCode().value()).isEqualTo(401);
} }
private ResponseEntity<String> makeRestCallToGetPing(String username, String password) { private ResponseEntity<String> makeRestCallToGetPing(String username, String password) {