【问题标题】:Spring Security: How to use multiple URL patterns in FilterRegistrationBean?Spring Security:如何在 FilterRegistrationBean 中使用多个 URL 模式?
【发布时间】:2017-11-29 20:15:48
【问题描述】:

我有一颗豆子

@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 端点时没关系——过滤器按预期工作并拦截请求。

如何为我的案例使用多个 URL 模式(/api/cat/api/cat/**)?

PS

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

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

【问题讨论】:

  • @goat 你试过/api/cat/*
  • FilterRegistrationBean 的 javadoc 将很快更新,以提及它接受的 url 模式语法是根据 servlet 规范,因此用户不要将该模式与 spring 使用的 ant-matcher 模式混淆安全。

标签: java spring spring-security servlet-filters


【解决方案1】:

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

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

    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/*/

【讨论】:

    【解决方案2】:

    如果您查看文档

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

    当没有指定 URL 模式或 servlet 时,过滤器将关联到 '/*'

    如您所见,*spring 而不是 ** 使用的模式。 ** 通常是 bashgolang 使用的 glob。但是 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>
    

    【讨论】:

    • 我认为如果您仅将/api/cat/*/api/dog/* 包含为过滤器,则不会捕获/api/cat/api/dog。您可能还需要在您的网址格式中包含/api/cat/api/dog
    • @TwiN,它已经存在于 OPs 问题中,这就是为什么要显示更多关于我删除它的模式的原因。但它现在更新为包括两者
    • @TwiN & Tarun 你是对的——我错误地认为这些模式应该是 Ant 匹配器风格的模式,就像在 spring 安全 url 模式中使用的那样。谢谢。
    【解决方案3】:

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

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

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

    所以如果我调用 http://server/api/animal/elephant 过滤器被击中,我不认为这是预期的行为,因为我已经设置了 url 模式

    【讨论】:

      猜你喜欢
      • 2018-08-31
      • 2015-05-11
      • 1970-01-01
      • 2011-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 2012-12-11
      相关资源
      最近更新 更多