我有一个使用OAuth身份验证的Spring Boot应用程序。除了身份验证之外,我还需要授权用户才能访问系统。我创建了一个自定义过滤器来授权用户。我只想在BasicAuthenticationFilter
之后才运行此过滤器。如果BasicAuthenticationFilter
没有运行,则我的过滤器也不应运行。
AuthorizationFilter.java
@Component
public class AuthorizationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
boolean isValidUser = true;
// we get the authenticated user from the context
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String id = (authentication == null)? "" : authentication.getName();
..
// code to get the user data from database using 'id' and set isValidUser flag
..
if(isValidUser) {
filterChain.doFilter(request, response);
}
else {
...
// handle UNAUTHORIZED
...
}
}
}
SecurityConfiguration.java
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(final HttpSecurity security) throws Exception {
security.requestMatchers()
.antMatchers("/actuator/health")
.and()
.authorizeRequests()
.antMatchers("/actuator/health").permitAll()
.and()
.csrf().disable();
security.cors();
// Custom filter to validate if user is authorized and active to access the system
security.addFilterAfter(new AuthorizationFilter(), BasicAuthenticationFilter.class);
}
}
问题:
即使我已允许'/ actuator / health'端点,我的自定义过滤器仍会为该端点运行。如何排除我的过滤器在'/ actuator / health'上运行?
完美的解决方案是仅在运行BasicAuthenticationFilter
时运行我的过滤器。这可能吗?怎么样?
AFAIK,针对此类问题的最佳解决方案是创建新的过滤器链。在您的情况下,对于需要身份验证的端点将有一个过滤器链,对于打开的端点(不需要任何身份验证)将有另一个过滤器链。这是未受保护的端点的示例过滤器链:
<bean id="openFilterChain" class="org.springframework.security.web.DefaultSecurityFilterChain">
<description>Pass the list of filters that you want to invoke for the given request matcher.</description>
<constructor-arg index="0" ref="infoRequestMatcher"/>
<constructor-arg index="1">
<list>
<ref bean="exceptionTranslationFilter"/>
</list>
</constructor-arg>
</bean>
<bean id="infoRequestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<description>
Pass the request matcher that matches all you unprotected endpoints.
</description>
<constructor-arg index="0" value="/actuator/health"/>
</bean>
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<description>
Register your custom filter chain here.
</description>
<constructor-arg>
<list>
<ref bean="openFilterChain"/>
<ref bean="otherSecurityFilterChain"/>
</list>
</constructor-arg>
</bean>