gpt4 book ai didi

Spring 3.2 长轮询导致 SPRING_SECURITY_CONTEXT 被清除

转载 作者:行者123 更新时间:2023-12-02 00:18:07 25 4
gpt4 key购买 nike

我正在使用 Spring 3.2 Milestone 1 来实现带有 long polling 的服务.然而,出于某种原因,Spring Security (3.1.2) 在第一个延迟结果过期(已达到异步超时并且 tomcat 以 http.200 响应)或将某些响应发送回客户端后立即清除 SPRING_SECURITY_CONTEXT。使用 Spring Security 3.1.0 这只会在某些情况下发生(HTTPS 和客户端在某些硬件防火墙后面)但是对于 3.1.2 它总是发生(在第一个 DefferedResult 完成之后)!

这里是日志相关部分的调试输出

DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/updates/events'; against '/login*'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 1 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@fc783ee2: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@fc783ee2: Principal: org.springframework.security.core.userdetails.User@33ca09: Username: nvrs; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 46EC76439E921FE347EC48ECF71C1258; Granted Authorities: ADMIN'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 2 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 3 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 4 of 11 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 5 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 6 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 7 of 11 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter'
DEBUG: org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter - SecurityContextHolder not populated with remember-me token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@fc783ee2: Principal: org.springframework.security.core.userdetails.User@33ca09: Username: nvrs; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 46EC76439E921FE347EC48ECF71C1258; Granted Authorities: ADMIN'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
DEBUG: org.springframework.security.web.authentication.AnonymousAuthenticationFilter - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@fc783ee2: Principal: org.springframework.security.core.userdetails.User@33ca09: Username: nvrs; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 46EC76439E921FE347EC48ECF71C1258; Granted Authorities: ADMIN'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/updates/events'; against '/updates/**'
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526; Attributes: [hasAnyRole('ADMIN','MANAGER','INTERNAL')]
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@fc783ee2: Principal: org.springframework.security.core.userdetails.User@33ca09: Username: nvrs; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 46EC76439E921FE347EC48ECF71C1258; Granted Authorities: ADMIN
DEBUG: org.springframework.security.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@52bf21bf, returned: 1
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Authorization successful
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - RunAsManager did not change Authentication object
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481959526 reached end of additional filter chain; proceeding with original chain
DEBUG: org.springframework.security.web.access.ExceptionTranslationFilter - Chain processed normally
DEBUG: org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
DEBUG: org.springframework.security.web.access.ExceptionTranslationFilter - Chain processed normally
DEBUG: org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
DEBUG: org.springframework.security.web.access.ExceptionTranslationFilter - Chain processed normally
DEBUG: org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/updates/events'; against '/login*'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/updates/events'; against '/resources/css/**'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/updates/events'; against '/resources/images/**'
DEBUG: org.springframework.security.web.util.AntPathRequestMatcher - Checking match of request : '/updates/events'; against '/resources/*'
DEBUG: org.springframework.security.web.FilterChainProxy - /updates/events?clientId=nvrs1346481959144&timestamp=0&_=1346481985081 at position 1 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@61ed10f7. A new one will be created.

如果仔细查看输出,您会看到第一个长轮询请求“/updates/events?”被正确处理 - 被授予访问权限,但之后 spring 安全上下文被清除,正如您从“HttpSession 为 SPRING_SECURITY_CONTEXT 返回空对象”行中看到的那样,这是由客户端在第一个过期后对该 URL 的另一个请求触发的,或者事件触发非空响应。我想在这里指出,我所有的自定义过滤器都已被禁用,并且在处理长轮询请求时,我将 DefferedResult 存储到一个 Map 中,其中 sessionId-clientid(对于每个页面实例浏览器选项卡都是唯一的)作为访问它的键,并且在收到 JMS 消息的情况下向客户端发送结果。

问题存在于 Spring Framework 3.2 M1 和最新的 3.2 快照构建与 Spring Security 3.1.2 或其在 Tomcat 7.0.28/7.0.29(默认和 APR 连接器)下的相应最新快照。

最佳答案

在调试器的帮助下,我得出了以下结论:

设置 DefferedResult 后,org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper 的方法 flush() 被调用,通过代理调用 saveContext ()org.springframework.security.web.context.HttpSessionSecurityContextRepository

@Override
protected void saveContext(SecurityContext context) {
final Authentication authentication = context.getAuthentication();
HttpSession httpSession = request.getSession(false);

// See SEC-776
if (authentication == null || authenticationTrustResolver.isAnonymous(authentication)) {
if (logger.isDebugEnabled()) {
logger.debug("SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.");
}

if (httpSession != null && !contextObject.equals(contextBeforeExecution)) {
// SEC-1587 A non-anonymous context may still be in the session
// SEC-1735 remove if the contextBeforeExecution was not anonymous
httpSession.removeAttribute(springSecurityContextKey);
}
return;
}

由于身份验证对象为空(由于 spring 安全上下文已被清除)该行httpSession.removeAttribute(springSecurityContextKey) 从 session 中删除 SPRING_SECURITY_CONTEXT,用户发出的下一个请求导致 session 没有安全上下文,因此用户被重定向到登录。除非我在这里遗漏了一些明显的东西,否则这是异步请求的一个交易破坏者。我想知道 Spring Security 团队是否意识到这个问题,以及他们是否计划在 3.2 发布之前修复它。与此同时,有人对适当的解决方法有任何建议吗?

编辑:目前作为一个临时解决方案,我通过在异步请求的情况下不编辑 session 来处理这个问题。具体来说,我修改了何时刷新 securityContext 的检查:

if (httpSession != null && !contextObject.equals(contextBeforeExecution))

if (httpSession != null && !contextObject.equals(contextBeforeExecution) && this.request.getAttribute("javax.servlet.async.request_uri") == null)

谢谢

关于Spring 3.2 长轮询导致 SPRING_SECURITY_CONTEXT 被清除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12238750/

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