我有两个spring-boot进程。我在这两个平台上都启用了Spring Security,并且我正在使用Spring Security OAuth2 SSO设置。我还在使用Eureka和Zuul来允许对Boot1的调用调用Boot2中的服务。UI使用Angular和对服务的REST调用,使用的令牌是Json Web令牌。
这一切似乎都很有效,当然是在UI中。所有请求都使用Authorization header (包含JWT)和服务中的spring安全过滤器成功解析JWT并从中提取安全上下文。作为Spring Web处理的一部分,它将一个jsessionid值添加到客户机的cookie中。
最近,我只在Boot1上使用了Spring security。当将rest服务调用到Boot1中时,最终使用Zuul将请求转发到Boot2,我在rest客户端中所需要的就是在JWT中包含Authorization头,一切都很正常。
然而,我最近向Boot2添加了Spring Security (使用@EnableResourceServer注释),现在rest调用失败,除非我同时拥有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的情况下进行rest调用,最终总是要创建一个新的DefaultOAuth2ClientContext,因为它试图创建会话作用域的bean。对于JSESSIONID,它使用了一个持久化的DefaultOAuth2ClientContext,它将具有上下文。
那么,在构造DefaultOAuth2ClientContext时,是否可以查看请求是否包含令牌并使用它?或者像这样的东西?我们正试图转向无状态服务,这似乎是实现这一目标的障碍。
发布于 2016-06-08 09:21:06
事实证明,这是系统的不同部分使用的client-id值的问题。
查看OAuth2TokenRelayFilter,如果为资源服务器(boot1)定义的客户端id与请求提供的令牌中包含的令牌的一部分所定义的客户端id匹配,则它将尝试刷新令牌。在我的例子中,这是真的:令牌是使用相同的client-id定义的。
这确实是不正确的。当我更新rest客户机以使用令牌,但在请求令牌时使用不同的client-id时,请求将按预期正确转发,而不需要jsessionid。这正是我想要的。
我怀疑这最终是由于我的系统的组件不正确地使用了client-id值造成的。
https://stackoverflow.com/questions/37670387
复制相似问题