休息调用需要JSESSIONID(Spring启动,Spring Security,OAuth2,Zuul)

时间:2016-06-07 04:15:40

标签: spring-security spring-boot spring-cloud

我有两个弹簧启动过程。我在两者上启用了Spring Security,我正在使用Spring Security OAuth2 SSO设置。我也使用Eureka和Zuul来允许调用Boot1来调用Boot2中的服务。 UI正在使用Angular和REST调用服务,正在使用的令牌是Json Web Token。

这一切似乎都有效,当然在UI中。所有请求都使用Authorization标头(包含JWT),服务中的spring安全过滤器成功解析JWT并从中提取安全上下文。作为Spring Web处理的一部分,它将JSESSIONID值添加到客户端的cookie中。

最近,我在Boot1上只有Spring安全性。当将休息服务调用到Boot1时,最终使用Zuul将请求转发到Boot2,我在休息客户端中所需要的只是在JWT中包含Authorization标头,并且一切正常。

但是,我最近将Spring Security添加到Boot2(使用@EnableResourceServer注释),现在休息调用失败,除非我同时拥有Authorization标头以及包含JSESSIONID值的Cookie标头。调用不会失败,但会返回空值。

我已启用日志记录到Spring Security,并在Boot1中正确验证所有内容。它将进入相同的ZuulFilter。但Boot2上没有任何活动。

Zuul中是否存在需要定义JSESSIONID值才能转发请求的内容?或者这是在Boot2中,由于引入了Spring Security过滤器,它期待JSESSIONID标头值?

---更新---

我已经逐步完成了boot1。从我所看到的,OAuth2TokenRelayFilter中的代码抛出异常。具体来说,方法getAccessToken正在调用restTemplate.getAccessToken()。getValue(第90行,版本1.1.0-RELEASE),它会抛出UserRedirectRequiredException。

因此,虽然TokenRelayFilter有一个令牌,但它正在尝试刷新它。当它收到异常时,它会抛出BadCredentialsException,而不是使用已经定义的内容。

---更新2 ---

在OAuth2RestOperationsConfiguration中设置断点,在没有JSESSIONID的情况下进行休息调用总是会创建一个新的DefaultOAuth2ClientContext,因为它正在尝试创建会话范围的bean。使用JSESSIONID,它使用持久化的DefaultOAuth2ClientContext,它将具有上下文。

那么,在构造DefaultOAuth2ClientContext时,是否有可能查看请求是否包含令牌并使用它?或者类似的东西?我们正试图转向无国籍服务,这似乎是一个障碍。

1 个答案:

答案 0 :(得分:0)

这结果是系统不同部分使用的client-id值的问题。

查看OAuth2TokenRelayFilter,如果为资源服务器(boot1)定义的client-id与定义为请求提供的令牌中包含的令牌的一部分匹配,则尝试刷新令牌。就我而言,这是真的:令牌是使用相同的客户端ID定义的。

这真的不对。当我更新我的休息客户端以使用令牌,但在请求令牌时使用不同的客户端ID时,请求按预期正确转发,而不需要jsessionid。这正是我想要的。

我怀疑这最终是由于我的系统组件错误地使用了client-id值。