|
28 | 28 | import org.springframework.context.annotation.Bean; |
29 | 29 | import org.springframework.context.annotation.Configuration; |
30 | 30 | import org.springframework.core.env.Environment; |
| 31 | +import org.springframework.http.HttpStatus; |
| 32 | +import org.springframework.security.access.AccessDeniedException; |
31 | 33 | import org.springframework.security.authentication.AuthenticationEventPublisher; |
32 | 34 | import org.springframework.security.authentication.AuthenticationManager; |
33 | 35 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
|
37 | 39 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
38 | 40 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
39 | 41 | import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; |
| 42 | +import org.springframework.security.web.access.AccessDeniedHandler; |
| 43 | +import org.springframework.security.web.access.AccessDeniedHandlerImpl; |
40 | 44 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; |
| 45 | +import org.springframework.security.web.csrf.InvalidCsrfTokenException; |
| 46 | +import org.springframework.security.web.csrf.MissingCsrfTokenException; |
41 | 47 | import org.springframework.security.web.header.writers.StaticHeadersWriter; |
42 | 48 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; |
| 49 | +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; |
43 | 50 |
|
44 | 51 | import javax.inject.Inject; |
| 52 | +import javax.servlet.ServletException; |
| 53 | +import javax.servlet.http.HttpServletRequest; |
| 54 | +import javax.servlet.http.HttpServletResponse; |
| 55 | +import java.io.IOException; |
45 | 56 | import java.util.List; |
46 | 57 |
|
47 | 58 | @Configuration |
@@ -96,7 +107,20 @@ protected void configure(HttpSecurity http) throws Exception { |
96 | 107 |
|
97 | 108 | // Perform CSRF check on the login form |
98 | 109 | http.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/login", "POST")); |
99 | | - |
| 110 | + |
| 111 | + http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() { |
| 112 | + final AntPathRequestMatcher matcher = new AntPathRequestMatcher("/login", "POST"); |
| 113 | + final AccessDeniedHandler defaultAccessDeniedHandler = new AccessDeniedHandlerImpl(); |
| 114 | + @Override |
| 115 | + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { |
| 116 | + if (matcher.matcher(request).isMatch() && accessDeniedException instanceof MissingCsrfTokenException) { |
| 117 | + response.sendRedirect(ServletUriComponentsBuilder.fromCurrentContextPath().path("/login").queryParam("error", "expired").build().toUriString()); |
| 118 | + } else { |
| 119 | + defaultAccessDeniedHandler.handle(request, response, accessDeniedException); |
| 120 | + } |
| 121 | + } |
| 122 | + }); |
| 123 | + |
100 | 124 | // Always set header: X-Content-Type-Options=nosniff |
101 | 125 | http.headers().contentTypeOptions(); |
102 | 126 |
|
|
0 commit comments