Spring Security:如何在FilterRegistrationBean中使用多个URL模式?

时间:2017-06-26 21:36:24

标签: java spring spring-security servlet-filters

我有一个豆子

@Bean
public FilterRegistrationBean animalsFilterRegistration() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new AnimalsFilter());
    registration.addUrlPatterns(
        "/api/cat",
        "/api/cat/**",
        "/api/dog"
    );
    ...
    return registration;
}

在该bean中,我对/api/cat**个URL使用了两种模式。问题是,当我尝试使用复杂的后缀(/api/cat/1/feed)调用端点时,我的过滤器不会拦截请求。但是,当我调用/api/cat/api/got个端点时,它就可以了 - 过滤器按预期工作并拦截请求。

如何为我的案例使用多种网址格式(/api/cat/api/cat/**)?

PS

我尝试使用下一个模式组合:

1) /api/cat, /api/cat**, /api/dog
2) /api/cat, /api/cat/**, /api/dog
3) /api/cat**, /api/dog

3 个答案:

答案 0 :(得分:6)

如@Tarun Lalwani所述,您需要使用*而不是**,因为**在这种情况下不是有效的网址格式。

在您的情况下,请尝试以下操作:

    registration.addUrlPatterns(
        "/api/cat",
        "/api/cat/*",
        "/api/dog",
        "/api/dog/*"
    );

符合/api/cat/1/api/cat/1/feed/api/dog/1/api/dog/1/feed,...

如果您想要复制/api/*只会匹配/api/this/api/not/that的行为,那么您需要使用以下模式:/api/*/

答案 1 :(得分:6)

如果查看文档

https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/api/org/springframework/boot/web/servlet/FilterRegistrationBean.html

  

如果未指定网址格式或servlet,则过滤器将与' / *'

相关联

正如您所看到的,*spring而非**使用的模式。 **通常是bashgolang使用的全局。但是spring只使用*。所以你需要的只是

registration.addUrlPatterns(
        "/api/cat",
        "/api/cat/*",
        "/api/dog",
        "/api/dog/*"
    );

**模式通常用于安全过滤器

https://docs.spring.io/spring-security/site/docs/current/reference/html/security-filter-chain.html#filter-chain-proxy

<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
    <list>
    <sec:filter-chain pattern="/restful/**" filters="
        securityContextPersistenceFilterWithASCFalse,
        basicAuthenticationFilter,
        exceptionTranslationFilter,
        filterSecurityInterceptor" />
    <sec:filter-chain pattern="/**" filters="
        securityContextPersistenceFilterWithASCTrue,
        formLoginFilter,
        exceptionTranslationFilter,
        filterSecurityInterceptor" />
    </list>
</constructor-arg>
</bean>

答案 2 :(得分:0)

我的问题是:在每次端点调用时都调用过滤器,而忽略了我设置的模式:

myBean.setUrlPatterns(Arrays.asList("/cat/*","/dog/*","/serpent/*"));

我已经在@SpringBootApplication类中创建了bean。

因此,如果我调用http:// server / api / animal / elephant,则过滤器将被命中,并且由于设置了网址格式,我不认为这是预期的行为