Spring Security允​​许未经授权的用户从转发中访问受限制的URL

Pau*_*kin 0 spring-mvc spring-security

Spring Security 3.2.0.RC2

鉴于:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
        .authorizeRequests()
            .antMatchers("/restricted/**").hasRole("admin")
            .anyRequest().authenticated()

        // etc
        ;
 }
Run Code Online (Sandbox Code Playgroud)

没有管理员角色的用户尝试正确访问/myapp/restricted/foo.request会收到HTTP 403.

但是,鉴于:

@Controller
public class FooController {
    @RequestMapping("/bar.request")
    public String bar() {
        return "forward:/restricted/foo.request";
    }
}
Run Code Online (Sandbox Code Playgroud)

如果用户访问/myapp/bar.request,则将用户转发到受限制的/myapp/restricted/foo.request.如果没有明确阻止"/bar.request",如何阻止它?

Rob*_*nch 6

@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>
Run Code Online (Sandbox Code Playgroud)

要使用Java Configuration执行此操作,您将使用以下命令:

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    protected  EnumSet<DispatcherType> getSecurityDispatcherTypes() {
        return return EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC, DispatcherType.FORWARD);
    }

}
Run Code Online (Sandbox Code Playgroud)

最后一部分是默认情况下FilterSecurityInterceptor(确保URL受保护的部分)只拦截REQUEST而不是其他调度(即转发).这样做是因为保护转发到的URL非常少见(通常会保护转发的URL).要启用它,您需要在xml配置中使用以下内容,您需要使用http @ once-per-request = true:

<http once-per-request="true">
   <!-- ... -->
</http>
Run Code Online (Sandbox Code Playgroud)

类似地,Java Configuration中可以使用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
        ;
}
Run Code Online (Sandbox Code Playgroud)