【问题标题】:Exclude custom filter for some URL in Spring Boot在 Spring Boot 中排除某些 URL 的自定义过滤器
【发布时间】:2023-03-18 06:28:01
【问题描述】:

我有一个使用 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);
    }
}

问题:

  1. 即使我已允许“/actuator/health”端点,我的自定义过滤器仍会针对该端点运行。如何排除我的过滤器在“/actuator/health”上运行?

  2. 完美的解决方案是仅在 BasicAuthenticationFilter 运行时运行我的过滤器。这可能吗?怎么样?

【问题讨论】:

  • 在你的 AuthorizationFilter final String header = request.getHeader("Authorization"); if (header != null && header.startsWith("Basic ")) { put your filter code or filter buisiness logic } chain.doFilter(request, response);
  • 应该可以解决你的问题。
  • 所以基本上我必须检查是否提供了任何令牌。如果我得到的结果与将“身份验证”对象设为 null 一样,我不应该运行我的过滤器吗?
  • 与 BasicAuthenticationFilter 中的情况相同

标签: spring-boot spring-security oauth spring-security-oauth2 servlet-filters


【解决方案1】:

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 2015-03-06
    • 2020-07-18
    相关资源
    最近更新 更多