Spring Security自定义筛选器创建无限循环

nue99wik  于 2023-03-11  发布在  Spring
关注(0)|答案(3)|浏览(151)

依赖性: Spring Boot 1.1.5.释放,Spring4.0.6.释放,Spring安全3.2.4.释放
问题:我正在创建一个自定义筛选器,该筛选器基于请求中的令牌查询提供程序以验证用户。自定义筛选器代码和配置为here。正如您所看到的,我已尽可能多地禁用该筛选器以查明问题所在。启用调试会显示

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  CustomAuthenticationFilter
  SecurityContextPersistenceFilter
  SecurityContextHolderAwareRequestFilter
  FilterSecurityInterceptor
]

另一件事是,日志告诉我,用户已通过身份验证。
当查询应用程序时,会发生无限循环,最终请求返回,curl说它不能遵循那么多重定向, Postman 说服务器有问题。我读过一些关于无限循环的帖子,因为登录页面是安全的。在我的情况下,我不想在我的应用程序中启用任何登录。如果我不能验证用户,那么401/403状态将返回。请记住,应用程序充当客户端请求的身份验证代理,但它本身并不是客户端。我请求帮助,要么查明当前配置中的错误,要么确认我的方法不起作用?无论哪种方式,都要提前感谢您的帮助。

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig
    extends WebSecurityConfigurerAdapter {
    @Value("${oauth.check_token.url:http://localhost:3030/oauth/token/info}")
    private String checkTokenUrl;

    @Autowired @Qualifier("restTemplate")
    private RestOperations authRestTemplate;

[EDIT]我发现如果我不使用postman,如果我不告诉curl跟随重定向,无限循环就会停止。下面是如果我把CustomAuthenticationFilter放在SecurityContextPersistentFilter之前,我得到的完整日志。

************************************************************

    Request received for GET '/test-oauth':

    org.apache.catalina.connector.RequestFacade@35a0339c

    servletPath:/test-oauth
    pathInfo:null
    headers: 
    user-agent: curl/7.30.0
    host: localhost:8081
    accept: */*
    authorization: Bearer 8f58520f137b25b096b48a67135c5b9b294892a8c712d5c2bcb8d90ab9f6efd0

    Security filter chain: [
      WebAsyncManagerIntegrationFilter
      CustomAuthenticationFilter
      SecurityContextPersistenceFilter
      SecurityContextHolderAwareRequestFilter
      FilterSecurityInterceptor
    ]

    ************************************************************

    2014-08-23 18:54:39.453 DEBUG --- [nio-8081-exec-1] CustomAuthenticationFilter : Request is to process authentication
    2014-08-23 18:54:39.453 DEBUG --- [nio-8081-exec-1] CustomAuthenticationFilter : Attempting to authenticate: Bearer 8f58520f137b25b096b48a67135c5b9b294892a8c712d5c2bcb8d90ab9f6efd0
    2014-08-23 18:54:39.569 DEBUG --- [nio-8081-exec-1] CustomAuthenticationFilter : Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@93e3eff0: Principal: com.shift.sysops.auth.AuthSSOUser@f02988d6: Username: username; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER

如果我将自定义过滤器放在任何其他位置,它将抛出NPE,因为SecurityContextRepository在SecurityContextPersistenceFilter中为空。

2014-08-23 18:41:50.060 ERROR --- [nio-8081-exec-1] [dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.lang.NullPointerException: null
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:82)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.security.web.debug.DebugFilter.invokeWithWrappedRequest(DebugFilter.java:70)
    at org.springframework.security.web.debug.DebugFilter.doFilter(DebugFilter.java:59)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.java:89)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1720)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
nhhxz33t

nhhxz33t1#

据我所知,您有以下使用情形:
1.用户通过某个第三方应用程序(即非您的应用程序)进行身份验证
1.用户访问应用后,您将获取auth头并检查用户是否经过身份验证。
1.如果他通过了身份验证,您可以获取他的权限、详细信息等,并允许他访问您的应用程序
1.如果他没有通过身份验证,您将发送401错误响应。
对于此用例,最好扩展AbstractPreAuthenticatedProcessingFilter。
1.您可以通过扩展AbstractPreAuthenticatedProcessingFilter来定义自定义预身份验证筛选器。
1.在自定义过滤器中,您需要覆盖两个方法getPreAuthenticatedPrincipal()和getPreAuthenticatedCredentials()
1.在getPreAuthenticatedPrincipal()中,您可以检查请求中是否存在身份验证标头,如果存在,则在中返回标头名称作为主体,并在凭据中返回标头值
1.使用PreAuthenticatedAuthenticationProvider并提供自定义的preAuthenticatedUserDetailsService(通过扩展AuthenticationUserDetailsService)以检查身份验证令牌是否有效,如果有效,还获取授予的权限,否则引发AuthenticationException,如BadCredentialsException
1.创建您的自定义AuthenticationEntryPoint实现AuthenticationEntryPoint,并覆盖begin方法以返回401响应。
如果存在有效的身份验证报头,则预身份验证过滤器将在springSecurityContext中设置已验证用户,如果身份验证报头缺失/无效,则将返回402错误响应。
希望有帮助。

mnemlml8

mnemlml82#

我已经想出了两个解决方案,满足我的用例。如果你遇到这个职位与一个更好的答案,请分享它。

  1. Override AnonymousAuthenticationFilter
  2. Extend AbstractAutenticationProcessingFilter .
sulc1iza

sulc1iza3#

也许它可以帮助一些不得不处理这个问题的人:在我的例子中,在Tomcat中启动Web应用程序时,org.apache. Catalina .authenticator.AuthenticatorBase.invoke 在无限循环中连续调用我的 OncePerRequestFilter
我在 shouldNotFilter 方法中放置了一个跟踪:

LOG.debug("REQUEST PATH: " + request.getServletPath());

我意识到被持续调用的路径与“swagger-resources”相关,我的解决方案是在 WebSecurityConfigurerAdapter 中排除它:

@Override
public void configure(final WebSecurity web) throws Exception {
    web.ignoring()
        .antMatchers("/your_problematic_path");
}

相关问题