From 906faa4fa6f2d844f249cf0572d9111ca2e32eee Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Thu, 4 Jan 2024 17:43:24 +0200 Subject: [PATCH] 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 --- .../spring-security-web-boot-2/pom.xml | 19 +++-- .../customlogouthandler/MvcConfiguration.java | 30 +++---- .../services/UserCache.java | 4 +- .../customlogouthandler/user/User.java | 2 +- .../web/CustomLogoutHandler.java | 4 +- .../h2/config/SecurityConfiguration.java | 25 +++--- .../loginredirect/LoginPageFilter.java | 14 ++-- .../loginredirect/LoginPageInterceptor.java | 6 +- .../LoginRedirectSecurityConfig.java | 37 ++++----- .../MultipleAuthProvidersSecurityConfig.java | 22 +++-- .../MultipleEntryPointsSecurityConfig.java | 57 +++++++------ .../MultipleLoginSecurityConfig.java | 81 +++++++++---------- .../java/com/baeldung/ssl/SecurityConfig.java | 11 ++- .../CustomLogoutHandlerIntegrationTest.java | 11 +-- .../h2/web/UserControllerLiveTest.java | 4 +- .../web/HttpsApplicationIntegrationTest.java | 11 ++- ...thProvidersApplicationIntegrationTest.java | 8 +- 17 files changed, 179 insertions(+), 167 deletions(-) diff --git a/spring-security-modules/spring-security-web-boot-2/pom.xml b/spring-security-modules/spring-security-web-boot-2/pom.xml index d3684dd282..7ab48af2ed 100644 --- a/spring-security-modules/spring-security-web-boot-2/pom.xml +++ b/spring-security-modules/spring-security-web-boot-2/pom.xml @@ -11,8 +11,9 @@ com.baeldung - spring-security-modules + parent-boot-3 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -34,7 +35,7 @@ org.thymeleaf.extras - thymeleaf-extras-springsecurity5 + thymeleaf-extras-springsecurity6 org.springframework.boot @@ -81,11 +82,6 @@ org.springframework.security spring-security-core - - javax.servlet.jsp.jstl - jstl-api - ${jstl.version} - org.springframework.security spring-security-config @@ -100,6 +96,15 @@ ${ehcache-core.version} jar + + io.rest-assured + rest-assured + test + + + org.apache.httpcomponents.client5 + httpclient5 + diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/MvcConfiguration.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/MvcConfiguration.java index a0900b976a..50b6d6bad6 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/MvcConfiguration.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/MvcConfiguration.java @@ -7,8 +7,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; 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.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler; @@ -27,27 +29,21 @@ public class MvcConfiguration { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.httpBasic() - .and() - .authorizeRequests() - .antMatchers(HttpMethod.GET, "/user/**") - .hasRole("USER") - .and() - .logout() - .logoutUrl("/user/logout") - .addLogoutHandler(logoutHandler) - .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)) - .permitAll() - .and() - .csrf() - .disable() - .formLogin() - .disable(); + http.httpBasic(Customizer.withDefaults()) + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> + authorizationManagerRequestMatcherRegistry.requestMatchers(HttpMethod.GET, "/user/**").hasRole("USER")) + .logout(httpSecurityLogoutConfigurer -> + httpSecurityLogoutConfigurer.logoutUrl("/user/logout") + .addLogoutHandler(logoutHandler) + .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)).permitAll()) + .securityContext(httpSecuritySecurityContextConfigurer -> httpSecuritySecurityContextConfigurer.requireExplicitSave(false)) + .csrf(AbstractHttpConfigurer::disable) + .formLogin(AbstractHttpConfigurer::disable); return http.build(); } @Bean - public JdbcUserDetailsManager jdbcUserDetailsManager() throws Exception { + public JdbcUserDetailsManager jdbcUserDetailsManager() { JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource); jdbcUserDetailsManager.setUsersByUsernameQuery("select login, password, true from users where login=?"); jdbcUserDetailsManager.setAuthoritiesByUsernameQuery("select login, role from users where login=?"); diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/services/UserCache.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/services/UserCache.java index b86edc0dee..a04de6a571 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/services/UserCache.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/services/UserCache.java @@ -3,8 +3,8 @@ package com.baeldung.customlogouthandler.services; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Service; diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/user/User.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/user/User.java index ca3a998c5c..153bdcd751 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/user/User.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/user/User.java @@ -1,6 +1,6 @@ package com.baeldung.customlogouthandler.user; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "users") diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/web/CustomLogoutHandler.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/web/CustomLogoutHandler.java index a89c9a570d..13609081a4 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/web/CustomLogoutHandler.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/customlogouthandler/web/CustomLogoutHandler.java @@ -1,7 +1,7 @@ package com.baeldung.customlogouthandler.web; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.logout.LogoutHandler; diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java index f648383892..bef724b718 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java @@ -3,10 +3,13 @@ package com.baeldung.jdbcauthentication.h2.config; import javax.sql.DataSource; 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.Configuration; 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.configurers.AbstractAuthenticationFilterConfigurer; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; import org.springframework.security.core.userdetails.User; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @@ -16,19 +19,15 @@ public class SecurityConfiguration { @Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { - httpSecurity.authorizeRequests() - .antMatchers("/h2-console/**") - .permitAll() - .anyRequest() - .authenticated() - .and() - .formLogin() - .permitAll(); - httpSecurity.csrf() - .ignoringAntMatchers("/h2-console/**"); - httpSecurity.headers() - .frameOptions() - .sameOrigin(); + httpSecurity.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> + authorizationManagerRequestMatcherRegistry + .requestMatchers(PathRequest.toH2Console()).permitAll().anyRequest().authenticated()) + .formLogin(AbstractAuthenticationFilterConfigurer::permitAll); + + httpSecurity.csrf(httpSecurityCsrfConfigurer -> httpSecurityCsrfConfigurer.ignoringRequestMatchers(PathRequest.toH2Console())); + + httpSecurity.headers(httpSecurityHeadersConfigurer -> + httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)); return httpSecurity.build(); } diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageFilter.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageFilter.java index 3c6d076756..0eb32beeb5 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageFilter.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageFilter.java @@ -1,17 +1,17 @@ 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.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.GenericFilterBean; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; class LoginPageFilter extends GenericFilterBean { diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageInterceptor.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageInterceptor.java index f08b824369..2adf80912b 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageInterceptor.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageInterceptor.java @@ -1,9 +1,9 @@ package com.baeldung.loginredirect; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +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.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginRedirectSecurityConfig.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginRedirectSecurityConfig.java index 2b69dc855b..c9aa607a9f 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginRedirectSecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginRedirectSecurityConfig.java @@ -4,6 +4,7 @@ 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.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -16,6 +17,8 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic @EnableWebSecurity class LoginRedirectSecurityConfig { + private static final String LOGIN_USER = "/loginUser"; + @Bean public InMemoryUserDetailsManager userDetailsService() { UserDetails user = User.withUsername("user") @@ -28,26 +31,20 @@ class LoginRedirectSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.addFilterAfter(new LoginPageFilter(), UsernamePasswordAuthenticationFilter.class) - .authorizeRequests() - .antMatchers("/loginUser") - .permitAll() - .antMatchers("/user*") - .hasRole("USER") - .and() - .formLogin() - .loginPage("/loginUser") - .loginProcessingUrl("/user_login") - .failureUrl("/loginUser?error=loginError") - .defaultSuccessUrl("/userMainPage") - .permitAll() - .and() - .logout() - .logoutUrl("/user_logout") - .logoutSuccessUrl("/loginUser") - .deleteCookies("JSESSIONID") - .and() - .csrf() - .disable(); + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> + authorizationManagerRequestMatcherRegistry.requestMatchers(LOGIN_USER).permitAll() + .requestMatchers("/user*").hasRole("USER")) + .formLogin(httpSecurityFormLoginConfigurer -> + httpSecurityFormLoginConfigurer.loginPage(LOGIN_USER) + .loginProcessingUrl("/user_login") + .failureUrl("/loginUser?error=loginError") + .defaultSuccessUrl("/userMainPage").permitAll()) + .logout(httpSecurityLogoutConfigurer -> + httpSecurityLogoutConfigurer + .logoutUrl("/user_logout") + .logoutSuccessUrl(LOGIN_USER) + .deleteCookies("JSESSIONID")) + .csrf(AbstractHttpConfigurer::disable); return http.build(); } diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java index fa2a7b2171..0ffdc54a0e 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java @@ -1,15 +1,21 @@ package com.baeldung.multipleauthproviders; 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.Configuration; 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.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; +@Configuration @EnableWebSecurity public class MultipleAuthProvidersSecurityConfig { @@ -28,14 +34,14 @@ public class MultipleAuthProvidersSecurityConfig { } @Bean - public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authManager) throws Exception { - http.httpBasic() - .and() - .authorizeRequests() - .antMatchers("/api/**") - .authenticated() - .and() - .authenticationManager(authManager); + public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authManager, HandlerMappingIntrospector introspector) throws Exception { + MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector); + http.httpBasic(Customizer.withDefaults()) + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> + authorizationManagerRequestMatcherRegistry + .requestMatchers(PathRequest.toH2Console()).authenticated() + .requestMatchers(mvcMatcherBuilder.pattern("/api/**")).authenticated()) + .authenticationManager(authManager); return http.build(); } diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java index 46fc4880fa..2eba2e52e3 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; 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.configurers.AbstractHttpConfigurer; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; 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.authentication.LoginUrlAuthenticationEntryPoint; 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.web.servlet.handler.HandlerMappingIntrospector; @Configuration @EnableWebSecurity public class MultipleEntryPointsSecurityConfig { @Bean - public UserDetailsService userDetailsService() throws Exception { + public UserDetailsService userDetailsService() { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); @@ -38,11 +41,14 @@ public class MultipleEntryPointsSecurityConfig { public static class App1ConfigurationAdapter { @Bean - public SecurityFilterChain filterChainApp1(HttpSecurity http) throws Exception { - http.antMatcher("/admin/**") - .authorizeRequests().anyRequest().hasRole("ADMIN") - .and().httpBasic().authenticationEntryPoint(authenticationEntryPoint()) - .and().exceptionHandling().accessDeniedPage("/403"); + public SecurityFilterChain filterChainApp1(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception { + MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector); + http.securityMatcher("/admin/**") + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> + authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/admin/**")).hasRole("ADMIN")) + .httpBasic(httpSecurityHttpBasicConfigurer -> httpSecurityHttpBasicConfigurer.authenticationEntryPoint(authenticationEntryPoint())) + .exceptionHandling(httpSecurityExceptionHandlingConfigurer -> + httpSecurityExceptionHandlingConfigurer.accessDeniedPage("/403")); return http.build(); } @@ -59,18 +65,24 @@ public class MultipleEntryPointsSecurityConfig { public static class App2ConfigurationAdapter { @Bean - public SecurityFilterChain filterChainApp2(HttpSecurity http) throws Exception { - http.antMatcher("/user/**") - .authorizeRequests().anyRequest().hasRole("USER") - .and().formLogin().loginProcessingUrl("/user/login") - .failureUrl("/userLogin?error=loginError").defaultSuccessUrl("/user/myUserPage") - .and().logout().logoutUrl("/user/logout").logoutSuccessUrl("/multipleHttpLinks") - .deleteCookies("JSESSIONID") - .and().exceptionHandling() - .defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPointWithWarning(), new AntPathRequestMatcher("/user/private/**")) - .defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPoint(), new AntPathRequestMatcher("/user/general/**")) - .accessDeniedPage("/403") - .and().csrf().disable(); + public SecurityFilterChain filterChainApp2(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception { + MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector); + http.securityMatcher("/user/**") + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> + authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/user/**")).hasRole("USER")) + .formLogin(httpSecurityFormLoginConfigurer -> + httpSecurityFormLoginConfigurer.loginProcessingUrl("/user/login") + .failureUrl("/userLogin?error=loginError") + .defaultSuccessUrl("/user/myUserPage")) + .logout(httpSecurityLogoutConfigurer -> + httpSecurityLogoutConfigurer.logoutUrl("/user/logout") + .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(); } @@ -90,11 +102,10 @@ public class MultipleEntryPointsSecurityConfig { public static class App3ConfigurationAdapter { @Bean - public SecurityFilterChain filterChainApp3(HttpSecurity http) throws Exception { - http.antMatcher("/guest/**") - .authorizeRequests() - .anyRequest() - .permitAll(); + public SecurityFilterChain filterChainApp3(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception { + MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector); + http.securityMatcher("/guest/**") + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/guest/**")).permitAll()); return http.build(); } } diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multiplelogin/MultipleLoginSecurityConfig.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multiplelogin/MultipleLoginSecurityConfig.java index e5079e5549..ad0495d510 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multiplelogin/MultipleLoginSecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/multiplelogin/MultipleLoginSecurityConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; 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.configurers.AbstractHttpConfigurer; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; 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.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; @Configuration @EnableWebSecurity public class MultipleLoginSecurityConfig { @Bean - public UserDetailsService userDetailsService() throws Exception { + public UserDetailsService userDetailsService() { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); @@ -44,30 +47,24 @@ public class MultipleLoginSecurityConfig { } @Bean - public SecurityFilterChain filterChainApp1(HttpSecurity http) throws Exception { - http.antMatcher("/admin*") - .authorizeRequests() - .anyRequest() - .hasRole("ADMIN") + public SecurityFilterChain filterChainApp1(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception { + MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector); + http.securityMatcher("/admin*") + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/admin*")).hasRole("ADMIN")) // log in - .and() - .formLogin() - .loginPage("/loginAdmin") - .loginProcessingUrl("/admin_login") - .failureUrl("/loginAdmin?error=loginError") - .defaultSuccessUrl("/adminPage") + .formLogin(httpSecurityFormLoginConfigurer -> + httpSecurityFormLoginConfigurer.loginPage("/loginAdmin") + .loginProcessingUrl("/admin_login") + .failureUrl("/loginAdmin?error=loginError") + .defaultSuccessUrl("/adminPage")) // logout - .and() - .logout() - .logoutUrl("/admin_logout") - .logoutSuccessUrl("/protectedLinks") - .deleteCookies("JSESSIONID") - .and() - .exceptionHandling() - .accessDeniedPage("/403") - .and() - .csrf() - .disable(); + .logout(httpSecurityLogoutConfigurer -> + httpSecurityLogoutConfigurer.logoutUrl("/admin_logout") + .logoutSuccessUrl("/protectedLinks") + .deleteCookies("JSESSIONID")) + .exceptionHandling(httpSecurityExceptionHandlingConfigurer -> + httpSecurityExceptionHandlingConfigurer.accessDeniedPage("/403")) + .csrf(AbstractHttpConfigurer::disable); return http.build(); } @@ -87,30 +84,24 @@ public class MultipleLoginSecurityConfig { } @Bean - public SecurityFilterChain filterChainApp2(HttpSecurity http) throws Exception { - http.antMatcher("/user*") - .authorizeRequests() - .anyRequest() - .hasRole("USER") + public SecurityFilterChain filterChainApp2(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception { + MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector); + http.securityMatcher("/user*") + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/user*")).hasRole("USER")) // log in - .and() - .formLogin() - .loginPage("/loginUser") - .loginProcessingUrl("/user_login") - .failureUrl("/loginUser?error=loginError") - .defaultSuccessUrl("/userPage") + .formLogin(httpSecurityFormLoginConfigurer -> + httpSecurityFormLoginConfigurer.loginPage("/loginUser") + .loginProcessingUrl("/user_login") + .failureUrl("/loginUser?error=loginError") + .defaultSuccessUrl("/userPage")) // logout - .and() - .logout() - .logoutUrl("/user_logout") - .logoutSuccessUrl("/protectedLinks") - .deleteCookies("JSESSIONID") - .and() - .exceptionHandling() - .accessDeniedPage("/403") - .and() - .csrf() - .disable(); + .logout(httpSecurityLogoutConfigurer -> + httpSecurityLogoutConfigurer.logoutUrl("/user_logout") + .logoutSuccessUrl("/protectedLinks") + .deleteCookies("JSESSIONID")) + .exceptionHandling(httpSecurityExceptionHandlingConfigurer -> + httpSecurityExceptionHandlingConfigurer.accessDeniedPage("/403")) + .csrf(AbstractHttpConfigurer::disable); return http.build(); } } diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/ssl/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/ssl/SecurityConfig.java index b92e83039b..b604497d1e 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/ssl/SecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/ssl/SecurityConfig.java @@ -1,18 +1,21 @@ package com.baeldung.ssl; 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.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; +@Configuration @EnableWebSecurity public class SecurityConfig { @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.authorizeRequests() - .antMatchers("/**") - .permitAll(); + public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception { + MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector); + http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers(mvcMatcherBuilder.pattern("/**")).permitAll()); return http.build(); } } diff --git a/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/customlogouthandler/CustomLogoutHandlerIntegrationTest.java b/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/customlogouthandler/CustomLogoutHandlerIntegrationTest.java index cd8a1a72d6..68e41c50ae 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/customlogouthandler/CustomLogoutHandlerIntegrationTest.java +++ b/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/customlogouthandler/CustomLogoutHandlerIntegrationTest.java @@ -7,7 +7,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; 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.HttpHeaders; import org.springframework.http.HttpMethod; @@ -21,7 +21,8 @@ import com.baeldung.customlogouthandler.services.UserCache; @RunWith(SpringJUnit4ClassRunner.class) @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") class CustomLogoutHandlerIntegrationTest { @@ -37,7 +38,7 @@ class CustomLogoutHandlerIntegrationTest { @Test public void whenLogin_thenUseUserCache() { // User cache should be empty on start - assertThat(userCache.size()).isEqualTo(0); + assertThat(userCache.size()).isZero(); // Request using first login ResponseEntity response = restTemplate.withBasicAuth("user", "pass") @@ -66,7 +67,7 @@ class CustomLogoutHandlerIntegrationTest { @Test public void whenLogout_thenCacheIsEmpty() { // User cache should be empty on start - assertThat(userCache.size()).isEqualTo(0); + assertThat(userCache.size()).isZero(); // Request using first login ResponseEntity response = restTemplate.withBasicAuth("user", "pass") @@ -89,7 +90,7 @@ class CustomLogoutHandlerIntegrationTest { // User cache must be empty now // this is the reaction on custom logout filter execution - assertThat(userCache.size()).isEqualTo(0); + assertThat(userCache.size()).isZero(); // Assert unauthorized request response = restTemplate.exchange(getLanguageUrl(), HttpMethod.GET, new HttpEntity(requestHeaders), String.class); diff --git a/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java b/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java index 12b5ca5867..5f869c4677 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java +++ b/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java @@ -17,10 +17,10 @@ public class UserControllerLiveTest { private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; @Test - public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { + public void givenExisting_whenRequestPrincipal_thenRetrieveData() { SessionFilter filter = new SessionFilter(); given().auth() - .form("user", "pass", new FormAuthConfig("/login", "username", "password").withCsrfFieldName("_csrf")) + .form("user", "pass", new FormAuthConfig("/login", "username", "password").withAdditionalField("_csrf")) .and() .filter(filter) .when() diff --git a/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/web/HttpsApplicationIntegrationTest.java b/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/web/HttpsApplicationIntegrationTest.java index 63d47e6a46..7d1b17efed 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/web/HttpsApplicationIntegrationTest.java +++ b/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/web/HttpsApplicationIntegrationTest.java @@ -1,8 +1,10 @@ package com.baeldung.web; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.HttpClients; +import org.apache.hc.client5.http.classic.HttpClient; +import org.apache.hc.client5.http.impl.classic.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 com.baeldung.ssl.HttpsEnabledApplication; import org.junit.Test; @@ -47,8 +49,9 @@ public class HttpsApplicationIntegrationTest { SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()) .build(); SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext); + HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(socketFactory).build(); HttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(socketFactory) + .setConnectionManager(connectionManager) .build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); return new RestTemplate(factory); diff --git a/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java b/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java index c5ef469fe8..0c94cccbdd 100644 --- a/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java +++ b/spring-security-modules/spring-security-web-boot-2/src/test/java/com/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java @@ -24,7 +24,7 @@ public class MultipleAuthProvidersApplicationIntegrationTest { public void givenMemUsers_whenGetPingWithValidUser_thenOk() { ResponseEntity result = makeRestCallToGetPing("memuser", "pass"); - assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getStatusCode().value()).isEqualTo(200); assertThat(result.getBody()).isEqualTo("OK"); } @@ -32,7 +32,7 @@ public class MultipleAuthProvidersApplicationIntegrationTest { public void givenExternalUsers_whenGetPingWithValidUser_thenOK() { ResponseEntity result = makeRestCallToGetPing("externaluser", "pass"); - assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getStatusCode().value()).isEqualTo(200); assertThat(result.getBody()).isEqualTo("OK"); } @@ -40,14 +40,14 @@ public class MultipleAuthProvidersApplicationIntegrationTest { public void givenAuthProviders_whenGetPingWithNoCred_then401() { ResponseEntity result = makeRestCallToGetPing(); - assertThat(result.getStatusCodeValue()).isEqualTo(401); + assertThat(result.getStatusCode().value()).isEqualTo(401); } @Test public void givenAuthProviders_whenGetPingWithBadCred_then401() { ResponseEntity result = makeRestCallToGetPing("user", "bad_password"); - assertThat(result.getStatusCodeValue()).isEqualTo(401); + assertThat(result.getStatusCode().value()).isEqualTo(401); } private ResponseEntity makeRestCallToGetPing(String username, String password) {