@kungfuters 是正确的,第一步是确保过滤器首先拦截该请求。要使用 web.xml 执行此操作,您将使用以下内容:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher> <!-- Include FORWARD here -->
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
要使用 Java 配置执行此操作,您将使用以下内容:
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
protected EnumSet<DispatcherType> getSecurityDispatcherTypes() {
return return EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC, DispatcherType.FORWARD);
}
}
最后一点是 FilterSecurityInterceptor(确保 URL 受到保护的部分)默认只会拦截 REQUEST 而不会拦截额外的调度(即转发)。这样做是因为很少保护转发到的 URL(通常您会保护进行转发的 URL)。要启用它,您需要将以下内容与 xml 配置一起使用,您需要使用http@once-per-request=true:
<http once-per-request="true">
<!-- ... -->
</http>
类似地,Java 配置中有一个 oncePerRequest 属性可以使用。例如:
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.filterSecurityInterceptorOncePerRequest(false)
// make sure to grant access to any login page you are forwarding to
.antMatchers("/restricted/login").permitAll()
.antMatchers("/restricted/**").hasRole("admin")
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
// etc
;
}