Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 3.2长轮询导致清除Spring\u安全\u上下文_Spring_Spring Security_Tomcat7 - Fatal编程技术网

Spring 3.2长轮询导致清除Spring\u安全\u上下文

Spring 3.2长轮询导致清除Spring\u安全\u上下文,spring,spring-security,tomcat7,Spring,Spring Security,Tomcat7,我正在使用Spring3.2里程碑1来实现一个服务。但是,由于某些原因,Spring Security(3.1.2)在第一个差异结果过期(已达到asynctimeout,tomcat使用http.200响应)或将某些响应发送回客户端后立即清除Spring_Security_上下文。使用SpringSecurity3.1.0,这种情况仅在某些情况下发生(HTTPS和客户端位于某些硬件防火墙之后),但在3.1.2中,这种情况总是发生(在第一个DefferedResult完成之后) 下面是日志相关部分

我正在使用Spring3.2里程碑1来实现一个服务。但是,由于某些原因,Spring Security(3.1.2)在第一个差异结果过期(已达到asynctimeout,tomcat使用http.200响应)或将某些响应发送回客户端后立即清除Spring_Security_上下文。使用SpringSecurity3.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\u安全\u上下文的空对象”一行中看到的那样在第一个URL过期后,客户端对该URL的另一个请求会触发该URL,或者某个事件会触发非emty响应。 我想在此指出,我所有的自定义过滤器都已禁用,在处理长轮询请求时,我将差异结果存储到带有sessionId clientid(对于每个页面实例浏览器选项卡都是唯一的)的映射中,作为访问该映射的键,并在收到JMS消息时向客户端发送结果


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

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

在设置了不同的结果之后,
org.springframework.security.web.context.saveContextOnUpdate或ErrorResponseRapper的方法
flush()
,通过代理调用
org.springframework.security.web.context.HttpSessionSecurityContextRepository的
saveContext()

@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;
    }
由于身份验证对象为null(由于spring安全上下文已被清除),因此 httpSession.removeAttribute(springSecurityContextKey)从会话中删除SPRING_SECURITY_上下文,用户发出的下一个请求将导致没有安全上下文的会话,因此用户被重定向到登录。 除非我在这里遗漏了一些明显的东西,否则这是异步请求的交易破坏者。我想知道Spring安全团队是否意识到这个问题,他们是否计划在3.2发布之前修复它。 同时,有没有人对适当的解决方法有什么建议

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

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


谢谢

您是否在服务器端使用分叉线程

我们有一个类似的安全上下文被清除的问题,因为我们有
分叉线程
与响应交互。安全上下文是一个
线程本地
变量,默认情况下不与分叉线程共享(请参阅)

我们通过将
SecurityContextHolder
策略设置为
模式\u INHERITABLETHREADLOCAL
,解决了此问题:

spring安全配置xml:

<beans:bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass" value="org.springframework.security.core.context.SecurityContextHolder" />
    <property name="targetMethod" value="setStrategyName" />
    <property name="arguments" value="MODE_INHERITABLETHREADLOCAL" />
</beans:bean>

更新2016-10-31

在使用线程池(例如Tomcat)的环境中,使用
INHERITABLETHREADLOCAL
可能会导致ThreadLocal泄漏。
还有其他方法(例如,使用
delegatingsecuritycontextrunable
)确保分叉线程获得正确的Spring安全上下文。请参阅。

这里没有任何异常的证据(也没有在下面的答案中)。更可能的解释是,由于某种原因(例如,由于HTTP/HTTPS之间的切换),您正在丢失会话,因此会得到一个空上下文。你需要证明事实并非如此。我绝对不会在HTTP和HTTPS之间切换。我将尝试做一些更合适的事情来展示我所说的内容,比如说“身份验证对象为空”。为什么在这个请求过程中上下文被清除了?请记住,安全上下文是线程本地对象。这可能是您问题的一部分,而不是答案。正如您所说,安全上下文是线程本地的,据我所知,在保存异步请求时不会保存它。因此,当asyn上下文恢复时,身份验证对象为空。如果您能够清楚地演示该问题,那么在Spring问题跟踪器中可能会更好地处理它。我想在这里提出一个问题。Spring安全性中还没有实现异步支持。请跟随查看其进度。您应该尝试一下Spring3.2+SpringSecurity3.2(M1)。应该是固定的。
<beans:bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass" value="org.springframework.security.core.context.SecurityContextHolder" />
    <property name="targetMethod" value="setStrategyName" />
    <property name="arguments" value="MODE_INHERITABLETHREADLOCAL" />
</beans:bean>