spring security oauth2 禁用基于 jsessionid 的会话

Posted

技术标签:

【中文标题】spring security oauth2 禁用基于 jsessionid 的会话【英文标题】:spring security oauth2 disable jsessionid based session 【发布时间】:2015-04-01 14:01:46 【问题描述】:

我没有评论的声誉,否则这个post 描述了完全相同的问题。

我已经在一个 spring 4 应用程序中成功实现了 spring security oauth2 2.0.5。一切正常,我可以生成令牌并且 api 请求已正确验证。但问题是,一旦在基于浏览器的应用程序中使用访问令牌对 api 进行身份验证,后续调用就不需要访问令牌,因为 - 似乎 spring security 依赖于 sessionid 来识别和验证用户。 - 即使在访问令牌到期后,调用似乎也可以验证。

所以看来 spring 仅在第一次调用时依赖访问令牌,然后它依赖于 cookie/jsessionid。我尝试通过以下方式禁用该行为(向 sparklr2 学习)-

Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.anonymous().disable();
        //oauth2 recommends that oauth token url should be only available to authorized clients
        http.requestMatchers().antMatchers("/oauth/token").and().authorizeRequests().anyRequest().fullyAuthenticated();
        http.httpBasic().authenticationEntryPoint(oAuth2AuthenticationEntryPoint()).and()
                .addFilterBefore(clientCredentialsTokenEndpointFilter(), BasicAuthenticationFilter.class)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().exceptionHandling()
                .accessDeniedHandler(oAuth2AccessDeniedHandler);

    

但这无济于事。在日志中我可以看到 -

尝试使用 Ant [pattern='/oauth/token'] 进行匹配 请求:'/v1.0/printconfig/';针对 '/oauth/token' 尝试匹配 使用 Ant [pattern='/oauth/token_key'] 检查请求的匹配: '/v1.0/printconfig/';针对 '/oauth/token_key' 尝试匹配使用 Ant [pattern='/oauth/check_token'] 检查请求的匹配: '/v1.0/printconfig/';针对 '/oauth/check_token' 未找到匹配项 尝试使用 Ant [pattern='/v1.0/'] 进行匹配 请求:'/v1.0/printconfig/';针对 '/v1.0/' 匹配 /v1.0/printconfig/ 在附加过滤器链中的第 10 个位置; 触发过滤器:'WebAsyncManagerIntegrationFilter' /v1.0/printconfig/ 在附加过滤器链中的第 10 位中的第 2 位; 射击过滤器: 'SecurityContextPersistenceFilter' 获得了有效的 SecurityContext 来自 SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@bd392350: 验证: org.springframework.security.oauth2.provider.OAuth2Authentication@bd392350: 校长:org.springframework.security.core.userdetails.User@6d: 用户名:m;密码保护];启用:真;帐户未过期: 真的;凭据非过期:真; AccountNonLocked:真;的确 权限:ROLE_USER;凭证:[受保护];已认证:真实; 详细信息:remoteAddress=0:0:0:0:0:0:0:1, tokenValue=;的确 权限:ROLE_USER' /v1.0/printconfig/ 在位置 3 of 10 in 额外的过滤器链;触发过滤器:'HeaderWriterFilter' 不是 注入 HSTS 标头,因为它与 requestMatcher 不匹配 org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@6044b89b /v1.0/printconfig/ 在附加过滤器链中的第 10 位中的第 4 位; 触发过滤器:'LogoutFilter' 检查请求的匹配: '/v1.0/printconfig/';针对 '/logout' /v1.0/printconfig/ 在位置 附加过滤器链中的 10 个中的 5 个;发射过滤器: > 'OAuth2AuthenticationProcessingFilter' 标头中未找到令牌。 尝试请求参数。在请求参数中找不到令牌。不是 OAuth2 请求。请求中没有令牌,将继续链。 /v1.0/printconfig/ 在附加过滤器链中的第 6 个位置,共 10 个; 触发过滤器:'RequestCacheAwareFilter' /v1.0/printconfig/ at 附加过滤器链中的第 7 位,共 10 位;发射过滤器: 'SecurityContextHolderAwareRequestFilter' /v1.0/printconfig/ 在 附加过滤器链中的 10 位中的第 8 位;发射过滤器: 'SessionManagementFilter' /v1.0/printconfig/ 在 10 的第 9 位 额外的过滤器链;触发过滤器:'ExceptionTranslationFilter' /v1.0/printconfig/ 在附加过滤器链中的第 10 个位置,共 10 个; 触发过滤器:“FilterSecurityInterceptor”检查请求的匹配: '/v1.0/printconfig/';针对 '/v1.0/**' 安全对象: FilterInvocation: URL: /v1.0/printconfig/;属性: [#oauth2.throwOnError(hasRole('ROLE_USER'))] 先前已验证: org.springframework.security.oauth2.provider.OAuth2Authentication@bd392350: 校长:org.springframework.security.core.userdetails.User@6d: 用户名:m;密码保护];启用:真;帐户未过期: 真的;凭据非过期:真; AccountNonLocked:真;的确 权限:ROLE_USER;凭证:[受保护];已认证:真实; 详细信息:remoteAddress=0:0:0:0:0:0:0:1, tokenValue=;的确 当局:ROLE_USER 选民: org.springframework.security.web.access.expression.WebExpressionVoter@5f574bdc, 返回:1 授权成功 RunAsManager 没有变化 身份验证对象 /v1.0/printconfig/ 到达附加结束 过滤链;继续原链 链正常处理 SecurityContextHolder 现在已清除,因为请求处理已完成

如您所见,不存在 oauth 令牌标头,但仍然有不同的过滤器识别了会话。我很想禁用 sessionId 本身,但只需禁用 spring 对用户本身的身份验证就可以了。我希望访问令牌成为传入请求的唯一标识符。

【问题讨论】:

在我的情况下,我可以在 set-cookie 中看到 JSESSIONId,我不想使用,如何将令牌放在标题授权:Bearer 像这样而不是覆盖默认的 jsseionid 方式 oath2 【参考方案1】:

在我看来/v1.0/printconfig/OAuth2AuthenticationProcessingFilter 后面的受 OAuth2 保护的资源,而您的客户端发送的是 cookie 而不是令牌?如果这是正确的,那么 2.0.5 中的默认行为就是您所看到的(接受 cookie,并让您在自己的配置中控制访问规则)。在 2.0.6 中更改了默认值(除非明确配置资源服务器,否则 cookie 将不起作用:https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java#L94)。

【讨论】:

戴夫,根据您的项目,我正在使用带有 oauth2 的 facebook 登录。为什么 facebook 登录设置 cookie,我可以通过任何方式更改它以提供访问令牌。仅供参考,我有自己的 spring oauth 服务器。 我不太明白这个问题。当您通过 Facebook 进行身份验证时,您会获得一个 cookie。相当标准的东西,而不是你有任何影响力的东西。上面的教程链接中有一个身份验证服务器示例。也许这就是“提供访问令牌”的意思? 我正在创建休息服务,我的整个系统都在使用访问令牌和密码授权。现在因为我包括 FB 登录,FB Spring oauth 设置 cookie 来跟踪会话,cookie 不能在移动应用程序中使用。不知何故,在成功登录 FB 后,我需要为最终用户创建访问令牌,以便我的移动应用程序完好无损。如果您仍有疑问,请告诉我。 密码授予和 facebook 身份验证并没有真正混合,不是吗?您可能应该重新评估是否需要它。 在我的情况下,我可以在 set-cookie 中看到 JSESSIONId,我不想使用,如何将令牌放在标题授权:Bearer 像这样而不是覆盖默认的 jsseionid 方式 oath2

以上是关于spring security oauth2 禁用基于 jsessionid 的会话的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 1.5 禁用 oauth2 安全性

CORS 干扰 Spring Security oauth2

spring security oauth2 client_credentials 仅流程

Spring Security 入门(1-3)Spring Security oauth2.0 指南

我如何通过 Spring Security 创建 oauth 2 用户名密码流

Spring Security Oauth2