JAVA-29312 Upgrade spring-security-web-mvc (#15687)

Co-authored-by: timis1 <noreplay@yahoo.com>
This commit is contained in:
timis1
2024-01-20 01:03:25 +02:00
committed by GitHub
parent 699cd6e8cd
commit 1724f67a39
26 changed files with 153 additions and 161 deletions
@@ -1,36 +1,34 @@
package com.baeldung.clearsitedata;
import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.CACHE;
import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.COOKIES;
import static org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter.Directive.STORAGE;
import org.springframework.context.annotation.Bean;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.HeaderWriterLogoutHandler;
import org.springframework.security.web.header.writers.ClearSiteDataHeaderWriter;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableMethodSecurity
public class SpringSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/homepage.html", true)
.and()
.logout()
.logoutUrl("/baeldung/logout")
.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES, STORAGE)));
http.csrf(AbstractHttpConfigurer::disable)
.formLogin(httpSecurityFormLoginConfigurer ->
httpSecurityFormLoginConfigurer.loginPage("/login")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/homepage", true))
.logout(httpSecurityLogoutConfigurer ->
httpSecurityLogoutConfigurer.logoutUrl("/baeldung/logout")
.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES, STORAGE))));
return http.build();
}
}
@@ -3,9 +3,9 @@ package com.baeldung.security;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -61,9 +61,9 @@ public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSu
}
if (isUser) {
return "/homepage.html";
return "/homepage";
} else if (isAdmin) {
return "/console.html";
return "/console";
} else {
throw new IllegalStateException();
}
@@ -3,15 +3,15 @@ package com.baeldung.session.filter;
import java.io.IOException;
import java.util.Arrays;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class SessionFilter implements Filter{
@@ -3,6 +3,7 @@ package com.baeldung.session.security.config;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
@@ -11,7 +12,9 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import com.baeldung.security.MySimpleUrlAuthenticationSuccessHandler;
@@ -35,37 +38,28 @@ public class SecSecurityConfig {
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/anonymous*")
.anonymous()
.antMatchers("/login*", "/invalidSession*", "/sessionExpired*", "/foo/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login")
.successHandler(successHandler())
.failureUrl("/login.html?error=true")
.and()
.logout()
.deleteCookies("JSESSIONID")
.and()
.rememberMe()
.key("uniqueAndSecret")
.tokenValiditySeconds(86400)
.and()
.sessionManagement()
.sessionFixation()
.migrateSession()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.invalidSessionUrl("/invalidSession.html")
.maximumSessions(2)
.expiredUrl("/sessionExpired.html");
public SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
authorizationManagerRequestMatcherRegistry
.requestMatchers(mvc.pattern("/anonymous*")).anonymous()
.requestMatchers(mvc.pattern("/login*"), mvc.pattern("/invalidSession*"), mvc.pattern("/sessionExpired*"),
mvc.pattern("/foo/**")).permitAll()
.anyRequest().authenticated())
.formLogin(httpSecurityFormLoginConfigurer -> httpSecurityFormLoginConfigurer.loginPage("/login")
.loginProcessingUrl("/login")
.successHandler(successHandler())
.failureUrl("/login?error=true"))
.logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.deleteCookies("JSESSIONID"))
.rememberMe(httpSecurityRememberMeConfigurer ->
httpSecurityRememberMeConfigurer.key("uniqueAndSecret")
.tokenValiditySeconds(86400))
.sessionManagement(httpSecuritySessionManagementConfigurer ->
httpSecuritySessionManagementConfigurer.sessionFixation()
.migrateSession().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.invalidSessionUrl("/invalidSession")
.maximumSessions(2)
.expiredUrl("/sessionExpired"));
return http.build();
}
@@ -83,4 +77,8 @@ public class SecSecurityConfig {
return new BCryptPasswordEncoder();
}
@Bean
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
return new MvcRequestMatcher.Builder(introspector);
}
}
@@ -1,6 +1,6 @@
package com.baeldung.session.web;
import javax.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -1,6 +1,6 @@
package com.baeldung.session.web;
import javax.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -1,14 +1,13 @@
package com.baeldung.session.web.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import jakarta.servlet.ServletContext;
import org.springframework.web.WebApplicationInitializer;
public class MainWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext sc) throws ServletException {
public void onStartup(ServletContext sc) {
sc.getSessionCookieConfig().setHttpOnly(true);
sc.getSessionCookieConfig().setSecure(true);
}
@@ -9,13 +9,13 @@ public class MvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/anonymous.html");
registry.addViewController("/anonymous").setViewName("view/anonymous");
registry.addViewController("/login.html");
registry.addViewController("/homepage.html");
registry.addViewController("/sessionExpired.html");
registry.addViewController("/invalidSession.html");
registry.addViewController("/console.html");
registry.addViewController("/login").setViewName("view/login");
registry.addViewController("/homepage").setViewName("view/homepage");
registry.addViewController("/sessionExpired").setViewName("view/sessionExpired");
registry.addViewController("/invalidSession").setViewName("view/invalidSession");
registry.addViewController("/console").setViewName("view/console");
}
@@ -27,7 +27,8 @@ public class MvcConfig implements WebMvcConfigurer {
// final InternalResourceViewResolver bean = new InternalResourceViewResolver();
//
// bean.setViewClass(JstlView.class);
// bean.setPrefix("/WEB-INF/view/");
// bean.setPrefix("/templates/view/");
// bean.setSuffix(".jsp");
// return bean;
// }
}
@@ -2,8 +2,8 @@ package com.baeldung.web;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
import com.baeldung.monitoring.MetricRegistrySingleton;
import com.codahale.metrics.Counter;
@@ -0,0 +1,9 @@
<html>
<head></head>
<body>
<h1>Anonymous page</h1>
<a href="/login"/>To Login</a>
</body>
</html>
@@ -0,0 +1,20 @@
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head></head>
<body>
<h1>This is the landing page for the admin</h1>
<div sec:authorize="hasRole('ROLE_USER')">
This text is only visible to a user
<br/>
</div>
<div sec:authorize="hasRole('ROLE_ADMIN')">
This text is only visible to an admin
<br/>
</div>
<a href="/logout" />Logout</a>
</body>
</html>
@@ -0,0 +1,20 @@
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head></head>
<body>
<h1>This is the homepage for the user</h1>
<div sec:authorize="hasRole('ROLE_USER')">
This text is only visible to a user
<br />
</div>
<div sec:authorize="hasRole('ROLE_ADMIN')">
This text is only visible to an admin
<br />
</div>
<a href="/logout" />Logout</a>
</body>
</html>
@@ -0,0 +1,9 @@
<html>
<head></head>
<body>
<h1>Invalid Session Page</h1>
<a href="/login"/>To Login</a>
</body>
</html>
@@ -0,0 +1,9 @@
<html>
<head></head>
<body>
<h1>Session Expired Page</h1>
<a href="/login" />To Login</a>
</body>
</html>
@@ -1,10 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head></head>
<body>
<h1>Anonymous page</h1>
<a href="<c:url value="/login.html" />">To Login</a>
</body>
</html>
@@ -1,22 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
<html>
<head></head>
<body>
<h1>This is the landing page for the admin</h1>
<security:authorize access="hasRole('ROLE_USER')">
This text is only visible to a user
<br/>
</security:authorize>
<security:authorize access="hasRole('ROLE_ADMIN')">
This text is only visible to an admin
<br/>
</security:authorize>
<a href="<c:url value="/logout" />">Logout</a>
</body>
</html>
@@ -1,22 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags"%>
<html>
<head></head>
<body>
<h1>This is the homepage for the user</h1>
<security:authorize access="hasRole('ROLE_USER')">
This text is only visible to a user
<br />
</security:authorize>
<security:authorize access="hasRole('ROLE_ADMIN')">
This text is only visible to an admin
<br />
</security:authorize>
<a href="<c:url value="/logout" />">Logout</a>
</body>
</html>
@@ -1,10 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head></head>
<body>
<h1>Invalid Session Page</h1>
<a href="<c:url value="/login.html" />">To Login</a>
</body>
</html>
@@ -1,10 +0,0 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head></head>
<body>
<h1>Session Expired Page</h1>
<a href="<c:url value="/login.html" />">To Login</a>
</body>
</html>
@@ -13,7 +13,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.Filter;
import jakarta.servlet.Filter;
@ExtendWith(SpringExtension.class)
@WebAppConfiguration
@@ -35,11 +35,11 @@ public class SessionConfigurationLiveTest {
Response resp3 = simpleResponseRequestUsingSessionNotFollowingRedirects(sessionFilter);
assertThat(resp3.getStatusCode()).isEqualTo(HttpStatus.FOUND.value());
assertThat(resp3.getHeader("Location")).isEqualTo("http://localhost:8080/invalidSession.html");
assertThat(resp3.getHeader("Location")).isEqualTo("http://localhost:8080/invalidSession");
}
@Test
public void givenValidUser_whenLoginMoreThanMaxValidSession_thenRedirectedToExpiredSessionUri() throws Exception {
public void givenValidUser_whenLoginMoreThanMaxValidSession_thenRedirectedToExpiredSessionUri() {
SessionFilter sessionFilter = new SessionFilter();
simpleSvcRequestLoggingIn(sessionFilter);
simpleSvcRequestLoggingIn();
@@ -56,7 +56,7 @@ public class SessionConfigurationLiveTest {
.get(SESSION_SVC_URL);
assertThat(resp4.getStatusCode()).isEqualTo(HttpStatus.FOUND.value());
assertThat(resp4.getHeader("Location")).isEqualTo("http://localhost:8080/sessionExpired.html");
assertThat(resp4.getHeader("Location")).isEqualTo("http://localhost:8080/sessionExpired");
}
private static void simpleSvcRequestLoggingIn() {