gpt4 book ai didi

Spring Security 自定义过滤器创建无限循环

转载 作者:行者123 更新时间:2023-12-02 21:24:33 25 4
gpt4 key购买 nike

依赖项:Spring Boot 1.1.5.RELEASE、Spring 4.0.6.RELEASE、Spring Security 3.2.4.RELEASE

问题:我正在创建一个自定义过滤器,该过滤器基于请求中的 token 查询提供程序以对用户进行身份验证。自定义过滤器代码和配置为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;

[编辑]我发现如果我不使用 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 中为 null。

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)

最佳答案

据我了解,您有以下用例:

  1. 用户已通过某些第三方应用程序(即不是您的应用程序)进行身份验证

  2. 一旦用户访问您的应用程序,您就会获取 auth header 并检查是否 用户是否经过身份验证。

  3. 如果他已通过身份验证,您将获取 他的权限、详细信息等,并允许他访问您的 应用
  4. 如果他未通过身份验证,您将发送 401 错误响应。

对于此用例,最好扩展 AbstractPreAuthenticatedProcessingFilter。

  1. 您可以通过扩展来定义自定义预身份验证过滤器AbstractPreAuthenticatedProcessingFilter。
  2. 在自定义过滤器中,您需要重写两个方法 getPreAuthenticatedPrincipal() 和 getPreAuthenticatedCredentials()
  3. 在 getPreAuthenticatedPrincipal() 中,您可以检查请求中是否存在 auth header ,如果存在则返回 header 名称作为主体, header 值作为凭证
  4. 使用 PreAuthenticatedAuthenticationProvider 并提供您的自定义 preAuthenticatedUserDetailsS​​ervice(通过扩展 AuthenticationUserDetailsS​​ervice)来检查身份验证 token 是否有效,如果其有效还获取授予的权限,否则抛出 AuthenticationException,如 BadCredentialsException
  5. 创建实现 AuthenticationEntryPoint 的自定义 AuthenticationEntryPoint,并重写开始方法以返回 401 响应。

如果存在有效的身份验证 header ,预身份验证过滤器将在 springSecurityContext 中设置经过身份验证的用户,如果身份验证 header 丢失/无效,将返回 402 错误响应。

希望有帮助。

关于Spring Security 自定义过滤器创建无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25456897/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com