Spring Boot 安全性 - 两个不同的过滤器
Posted
技术标签:
【中文标题】Spring Boot 安全性 - 两个不同的过滤器【英文标题】:Spring boot security - two distinct filters 【发布时间】:2017-02-03 14:19:27 【问题描述】:我正在尝试使用两个不同的过滤器配置 Spring Security。 我想要的是有一些将由一个过滤器处理的 URL,以及一些将由其他过滤器处理的 URL。 这是我想出的设置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled=true)
public class SecurityConfigurationContext
@Order(1)
@Configuration
public static class ConfigurerAdapter1 extends WebSecurityConfigurerAdapter
...
@Override
protected void configure(final HttpSecurity http) throws Exception
// Handlers and entry points
http.exceptionHandling()
.authenticationEntryPoint(MyCustomAuthenticationEntryPoint);
http.authorizeRequests()
.antMatchers(HttpMethod.GET, "/filter1-urls/*").hasRole("USER");
http.addFilterBefore(myCustomFilter1, ChannelProcessingFilter.class);
http.csrf().disable();
http.httpBasic()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(myCustomAuthenticationService)
.passwordEncoder(new BCryptPasswordEncoder());
@Order(2)
@Configuration
public static class ConfigurerAdapter2 extends WebSecurityConfigurerAdapter
...
@Override
protected void configure(final HttpSecurity http) throws Exception
// Handlers and entry points
http.exceptionHandling()
.authenticationEntryPoint(MyCustomAuthenticationEntryPoint);
http.authorizeRequests()
.antMatchers(HttpMethod.GET, "/filter2-urls/*").hasRole("SUPER_USER");
http.addFilterBefore(myCustomFilter2, ChannelProcessingFilter.class);
http.csrf().disable();
http.httpBasic()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(myCustomAuthenticationService)
.passwordEncoder(new BCryptPasswordEncoder());
过滤器看起来像这样:
过滤器1:
@Component
@Order(1)
public final class MyCustomFilter1 implements Filter
public MyCustomFilter1()
super();
@Override
public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException
// logic for processing filter1-urls
过滤器2:
@Component
@Order(2)
public final class MyCustomFilter2 implements Filter
public MyCustomFilter2()
super();
@Override
public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException
// logic for processing filter2-urls
问题在于,对于每个请求,这两个过滤器都在一个链中调用。我提出的任何请求,它首先通过一个过滤器,然后通过另一个,而不是只通过一个。
我该如何解决这个问题?
提前致谢。
【问题讨论】:
【参考方案1】:你应该只有一个ConfigurerAdapter
。您可以将其组合成一个配置:
http.exceptionHandling()
.authenticationEntryPoint(MyCustomAuthenticationEntryPoint);
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/filter1-urls/*").hasRole("USER")
.antMatchers(HttpMethod.GET, "/filter2-urls/*").hasRole("SUPER_USER");
http.addFilterBefore(myCustomFilter, ChannelProcessingFilter.class);
将调用这两个过滤器,因为您设置了此类行为。你应该只留下一个过滤器来达到你想要的结果。
@Component
public final class MyCustomFilter implements Filter
public MyCustomFilter()
super();
@Override
public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException
// logic for processing filter2-urls and filter1-urls
无论如何,您的过滤器都会被链式调用。如果你想拆分你的过滤器,你应该在你的过滤器中添加if
语句来过滤只需要的url(你可以从ServletRequest
获取请求url
@Component
public final class MyCustomFilter2 implements Filter
public MyCustomFilter2()
super();
@Override
public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException
if (/*is filter2 urls*/)
// logic for processing filter2-urls
【讨论】:
嗯。谢谢。我会试一试,如果我成功了,请告诉你。以上是关于Spring Boot 安全性 - 两个不同的过滤器的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 安全性中,无法跳过登录 url 的 OncePerRequestFilter 过滤器(基本上是在初始登录期间获取 JWT 令牌)
Spring Security 具有不同用户详细信息的多个 HTTPSecurity 服务在 Spring Boot 中不起作用