|
28 | 28 | import jakarta.servlet.http.HttpSession; |
29 | 29 |
|
30 | 30 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
| 31 | +import org.springframework.boot.web.servlet.FilterRegistrationBean; |
31 | 32 | import org.springframework.context.annotation.Bean; |
32 | 33 | import org.springframework.context.annotation.Configuration; |
33 | 34 | import org.springframework.context.annotation.Import; |
|
40 | 41 | import org.springframework.security.core.context.SecurityContextHolder; |
41 | 42 | import org.springframework.security.web.SecurityFilterChain; |
42 | 43 | import org.springframework.security.web.access.AccessDeniedHandler; |
| 44 | +import org.springframework.security.web.authentication.logout.LogoutFilter; |
43 | 45 | import org.springframework.security.web.context.SecurityContextHolderFilter; |
| 46 | +import org.springframework.security.web.savedrequest.RequestCacheAwareFilter; |
44 | 47 | import org.springframework.web.filter.GenericFilterBean; |
| 48 | +import org.springframework.web.filter.OncePerRequestFilter; |
45 | 49 | import org.springframework.web.servlet.HandlerAdapter; |
46 | 50 | import org.springframework.web.servlet.HandlerMapping; |
47 | 51 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; |
@@ -73,38 +77,96 @@ public HandlerAdapter handlerAdapter() { |
73 | 77 | } |
74 | 78 |
|
75 | 79 | @Bean |
76 | | - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { |
| 80 | + public SecurityFilterChain securityFilterChain(HttpSecurity http, SimpleFilter simpleFilter, |
| 81 | + AnotherFilter anotherFilter) throws Exception { |
77 | 82 | http |
| 83 | + .csrf(csrf -> csrf.disable()) |
| 84 | + .cors(cors -> cors.disable()) |
78 | 85 | .addFilterBefore(new GenericFilterBean() { |
79 | 86 | @Override |
80 | 87 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
81 | 88 | throws IOException, ServletException { |
82 | 89 | SecurityContext securityContext = SecurityContextHolder.getContext(); |
83 | 90 | securityContext.setAuthentication(UsernamePasswordAuthenticationToken.authenticated("user", "password", |
84 | | - Collections.singleton(new SimpleGrantedAuthority("USER")))); |
| 91 | + Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")))); |
85 | 92 | HttpSession session = ((HttpServletRequest) request).getSession(); |
86 | 93 | session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext); |
87 | 94 | chain.doFilter(request, response); |
88 | 95 | } |
89 | 96 | }, SecurityContextHolderFilter.class) |
90 | | - .securityMatcher("/foo") |
91 | | - .authorizeHttpRequests(authorize -> authorize |
92 | | - .anyRequest().hasRole("FOO") |
93 | | - ) |
94 | | - .exceptionHandling(f -> f.accessDeniedHandler(accessDeniedHandler())); |
| 97 | + .securityMatcher("/foo/deny") |
| 98 | + .authorizeHttpRequests(auth -> { |
| 99 | + auth.anyRequest().hasRole("FOO"); |
| 100 | + }) |
| 101 | + .addFilterAfter(simpleFilter, LogoutFilter.class) |
| 102 | + .addFilterAfter(anotherFilter, RequestCacheAwareFilter.class) |
| 103 | + .exceptionHandling(f -> f.accessDeniedHandler(new MyAccessDeinedHandler())); |
95 | 104 | return http.build(); |
96 | 105 | } |
97 | 106 |
|
98 | 107 | @Bean |
99 | | - public AccessDeniedHandler accessDeniedHandler() { |
| 108 | + public FilterRegistrationBean<SimpleFilter> simpleFilterRegistration(SimpleFilter simpleFilter) { |
| 109 | + FilterRegistrationBean<SimpleFilter> registration = new FilterRegistrationBean<>(simpleFilter); |
| 110 | + registration.setEnabled(false); |
| 111 | + return registration; |
| 112 | + } |
100 | 113 |
|
101 | | - return new AccessDeniedHandler() { |
102 | | - @Override |
103 | | - public void handle(HttpServletRequest request, HttpServletResponse response, |
104 | | - AccessDeniedException accessDeniedException) throws IOException, ServletException { |
105 | | - response.sendError(403, "Can't touch this"); |
| 114 | + @Bean |
| 115 | + public FilterRegistrationBean<AnotherFilter> anotherFilterRegistration(AnotherFilter simpleFilter) { |
| 116 | + FilterRegistrationBean<AnotherFilter> registration = new FilterRegistrationBean<>(simpleFilter); |
| 117 | + registration.setEnabled(false); |
| 118 | + return registration; |
| 119 | + } |
| 120 | + |
| 121 | + @Bean |
| 122 | + public SimpleFilter simpleFilter() { |
| 123 | + return new SimpleFilter(); |
| 124 | + } |
| 125 | + |
| 126 | + @Bean |
| 127 | + public AnotherFilter anotherFilter() { |
| 128 | + return new AnotherFilter(); |
| 129 | + } |
| 130 | + |
| 131 | + public static class SimpleFilter extends OncePerRequestFilter { |
| 132 | + public boolean invoked; |
| 133 | + |
| 134 | + @Override |
| 135 | + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, |
| 136 | + FilterChain filterChain) throws ServletException, IOException { |
| 137 | + if (invoked) { |
| 138 | + throw new IllegalStateException("Filter has already been invoked"); |
| 139 | + } |
| 140 | + else { |
| 141 | + invoked = true; |
| 142 | + } |
| 143 | + |
| 144 | + filterChain.doFilter(request, response); |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + public static class AnotherFilter extends OncePerRequestFilter { |
| 149 | + public boolean invoked; |
| 150 | + @Override |
| 151 | + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, |
| 152 | + FilterChain filterChain) throws ServletException, IOException { |
| 153 | + if (invoked) { |
| 154 | + throw new IllegalStateException("Filter has already been invoked"); |
| 155 | + } |
| 156 | + else { |
| 157 | + invoked = true; |
106 | 158 | } |
107 | | - }; |
| 159 | + filterChain.doFilter(request, response); |
| 160 | + } |
108 | 161 | } |
109 | 162 |
|
| 163 | + public static class MyAccessDeinedHandler implements AccessDeniedHandler { |
| 164 | + |
| 165 | + @Override |
| 166 | + public void handle(HttpServletRequest request, HttpServletResponse response, |
| 167 | + AccessDeniedException accessDeniedException) throws IOException, ServletException { |
| 168 | + response.sendError(403, "Can't touch this"); |
| 169 | + } |
| 170 | + |
| 171 | + } |
110 | 172 | } |
0 commit comments