0

弹簧安全 3.2.0.RC2

鉴于:

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

        // etc
        ;
 }

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

但是,鉴于:

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

如果用户访问/myapp/bar.request,则用户被转发到受限的/myapp/restricted/foo.request。如何在不明确阻止“/bar.request”的情况下阻止它?

4

2 回答 2

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>

要使用 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
        ;
}
于 2013-11-14T18:03:45.590 回答
3

如果你使用 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>

...或使用基于 Servlet3 Java 的 Config 等效项,即扩展AbstractSecurityWebApplicationInitializer和覆盖该getSecurityDispatcherTypes()方法:

public class YourSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    protected  EnumSet<DispatcherType> getSecurityDispatcherTypes() {
        // Return dispatcher types here, in your case you'll want the defaults, 
        // which are DispatcherType.REQUEST and DispatcherType.ERROR
        // ...as well as the one you need for your use case: DispatcherType.FORWARD
    }

}

我在这里输入了,所以希望没有错误。不过,应该让你去。

于 2013-11-12T23:26:28.520 回答