Spring Security:如何在 FilterRegistrationBean 中使用多个 URL 模式?
Posted
技术标签:
【中文标题】Spring Security:如何在 FilterRegistrationBean 中使用多个 URL 模式?【英文标题】:Spring Security: How to use multiple URL patterns in FilterRegistrationBean? 【发布时间】: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 模式混淆安全。
【参考方案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
而不是 **
使用的模式。 **
通常是 bash
、golang
使用的 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 模式
【讨论】:
以上是关于Spring Security:如何在 FilterRegistrationBean 中使用多个 URL 模式?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring WebFlux Security(Reactive Spring Security)配置中将多个用户角色添加到单个 pathMatcher/Route?
如何在 spring-security 5.2 中增加 RemoteJWKSet 缓存 TTL
如何在 Spring Security 中将令牌转换为身份验证?
Spring Security:如何将两个应用程序与单独的 Spring Security 配置集成?