【问题标题】:spring-boot 1.3-M5 oauth2 SSO does not work with spring-session?spring-boot 1.3-M5 oauth2 SSO 不适用于 spring-session?
【发布时间】:2016-02-01 05:15:57
【问题描述】:

基本上我无法让 spring-boot oauth2 集成与 spring-session 一起使用。

我在 spring-boot 的问题跟踪器中创建了一个问题: https://github.com/spring-projects/spring-boot/issues/4360

我做了一个 repo 来演示这个问题

https://github.com/sloppycoder/spring-session-oauth-problem

有 2 个模块:

  • auth-server 是 oauth2 授权服务器。运行它,只需mvn。服务器将在http://localhost:19999/uaa
  • web-app 是使用 auth-server 进行单点登录的 Web 应用程序。 mvn 将在 http://localhost:8080 上启动应用程序

我的 sso 注销逻辑是这样工作的:

  1. 点击“注销”按钮将向http://localhost:19999/uaa/logout 发送一个POST,并在成功注销后传递URL 以重定向到http://localhost:8080/ssologout
  2. auth-server 注销并重定向到http://localhost:8080/ssologout
  3. http://localhost:8080/ssologout 然后发布到http://localhost:8080/logout
  4. (默认spring-security行为)注销后,重定向到http://localhost:8080/login?logout
  5. http://localhost:8080/login?logout 重定向到http://localhost:19999/uaa/login 并提示用户重新登录。

但是,在我引入春季课程后,第 5 步并没有发生。浏览器直接进入 web-app /dashboard。

确保在运行 sos-spring-session 分支之前启动本地 redis 守护进程。

我创建了 2 个分支来显示不同的行为:

  1. sso-only。 spring-boot 与 auth-server 集成,一切正常。
  2. sso-spring-sesson。注销不起作用。

github compare 显示了差异。

我将不胜感激有关如何解决此问题的任何建议和建议。

【问题讨论】:

    标签: java spring-mvc spring-boot spring-security-oauth2 spring-session


    【解决方案1】:

    我在 spring-boot 1.3.0.RC1、spring-session 和 redis 上遇到了类似的问题。

    spring-boot 1.3.0.RC1 : ClassCastException in getting oauth2 user info from session persisted in Redis

    如果您将过滤器顺序更改为,它可能会起作用

    'requestContextFilter'

    @Bean
    @ConditionalOnMissingBean(RequestContextFilter.class)
    public RequestContextFilter requestContextFilter() {
    
      return new RequestContextFilter();
    }
    
    @Bean
    public FilterRegistrationBean requestContextFilterChainRegistration(
      @Qualifier("requestContextFilter") Filter securityFilter) {
    
      FilterRegistrationBean registration = new FilterRegistrationBean(securityFilter);
      registration.setName("requestContextFilter");
    
      // note : must previous order of oAuth2ClientContextFilter
      registration.setOrder(SessionRepositoryFilter.DEFAULT_ORDER + 1);
    
      return registration;
    }
    
    @Bean
    public FilterRegistrationBean sessionRepositoryFilterRegistration(
      SessionRepositoryFilter sessionRepositoryFilter) {
    
      FilterRegistrationBean registration = new FilterRegistrationBean(sessionRepositoryFilter);
      registration.setName("springSessionRepositoryFilter");
    
      // note : must following order of oAuth2ClientContextFilter
      registration.setOrder(Integer.MAX_VALUE - 1);
    
      return registration;
    }
    

    你也可能需要删除依赖org.springframework.boot:spring-boot-devtools

    https://github.com/spring-projects/spring-boot/issues/3805相关


    后记:用于 spring-boot 1.3.3.RELEASE

    spring-session、redis、spring-security-oauth2 在过滤器顺序下工作。

    # logs on bootRun task
    Mapping filter: 'characterEncodingFilter' to: [/*]
    Mapping filter: 'springSessionRepositoryFilter' to: [/*]
    Mapping filter: 'requestContextFilter' to: [/*]
    Mapping filter: 'OAuth2ClientContextFilter' to: [/*]
    Mapping filter: 'springSecurityFilterChain' to: [/*]
    Mapping servlet: 'dispatcherServlet' to [/]
    

    当前所需的设置如下。

    @Bean
    @ConditionalOnMissingBean(RequestContextFilter.class)
    public RequestContextFilter requestContextFilter() {
      return new RequestContextFilter();
    }
    
    @Bean
    public FilterRegistrationBean requestContextFilterChainRegistration(
      @Qualifier("requestContextFilter") Filter securityFilter) {
    
      FilterRegistrationBean registration = 
        new FilterRegistrationBean(securityFilter);
    
      registration.setName("requestContextFilter");
    
      // note : must to be following order of springSessionRepositoryFilter
      registration.setOrder(SessionRepositoryFilter.DEFAULT_ORDER + 1);
    
      return registration;
    }
    

    【讨论】:

    【解决方案2】:

    该代码存在很多问题,但阻止它与 Spring Session 一起工作的一个问题是两个应用程序共享一个 cookie。 “主” webapp 的上下文路径是“/”,因此当身份验证服务器在同一主机上运行时,它会尝试使用相同的 cookie。使用本地会话时无关紧要,但是当您使用分布式会话时,当 2 个应用程序尝试共享同一个会话时,您会弄乱状态。您可以通过在 web 应用程序中使用 server.context-path(例如 /app)并对您的 HTML 等进行相应的更改来修复它,以确保浏览器遵循返回那里的路径。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-10
      • 2017-09-05
      • 2014-11-29
      • 2017-05-24
      • 2016-02-28
      • 2019-12-26
      • 1970-01-01
      • 2018-04-19
      相关资源
      最近更新 更多