1

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

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

我做了一个回购来证明这个问题

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

有2个模块:

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

  1. 单击“注销”按钮将执行 POST 到http://localhost:19999/uaa/logout,并在成功注销后传递 URL 以重定向到http://localhost:8080/ssologout
  2. auth-server 注销并重定向到http://localhost:8080/ssologout
  3. http://localhost:8080/ssologout然后 POST 到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比较显示了差异。

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

4

2 回答 2

1

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

spring-boot 1.3.0.RC1:从会话中获取 oauth2 用户信息的 ClassCastException 在 Redis 中持续存在

如果您将过滤器顺序更改为

'requestContextFilter' < 'OAuth2ClientContextFilter' < 'springSessionRepositoryFilter'

@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;
}
于 2015-11-02T06:55:49.127 回答
1

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

于 2015-11-02T15:01:29.613 回答