我有一个使用spring云组件(eureka,zuul和auth服务器)的本地协调环境。这些组件都是作为单独的独立服务实现的。然后我有越来越多的组合UI /资源服务,其中各个服务都有自己的用户界面。 UI使用thymeleaf模板放在服务器端,但本质上是在浏览器中运行的angularjs单页面应用程序。春云Zuul和JWT刷新令牌
单个Zuul服务面向所有的ui /资源服务。我注释了所有UI /资源服务@EnableResourceServer
并将@EnableOAuth2Sso
添加到Zuul服务器。
在application.properties对于Zuul我有以下特性:
security.oauth2.client.accessTokenUri=http://localhost:8771/uaa/oauth/token
security.oauth2.client.userAuthorizationUri=http://localhost:8771/uaa/oauth/authorize
security.oauth2.client.clientId=waharoa
security.oauth2.client.clientSecret=waharoa
security.oauth2.client.preEstablishedRedirectUri=http://localhost:81/login
security.oauth2.client.registeredRedirectUri=http://localhost:81/login
security.oauth2.client.useCurrentUri=false
security.oauth2.resource.jwt.keyValue=-----BEGIN PUBLIC KEY-----[ETC omitted]...
这一切都似乎工作作为标榜。我的问题是当令牌到期时。
在Auth服务器中,我设置令牌在60秒内到期,刷新令牌在12小时内过期。当令牌过期时,zuul服务器无法获得新的令牌。
在这出现在日志中的zuul服务器:
BadCredentialsException:无法获得通过OAuth2TokenRelayFilter.getAccessToken
更新抛出有效的访问令牌: 我打开调试org.springframework.security。 OAuth的在zuul服务,得到了以下
17:12:33.279 DEBUG o.s.s.o.c.t.g.c.AuthorizationCodeAccessTokenProvider - Retrieving token from http://localhost:8771/uaa/oauth/token
17:12:33.289 DEBUG o.s.s.o.c.t.g.c.AuthorizationCodeAccessTokenProvider - Encoding and sending form: {grant_type=[refresh_token], refresh_token=[eyJhbGciOiJS[...deleted...]VgGRHGT8OJ2yDfNVvNA]}
17:12:37.279 WARN o.s.c.n.z.f.post.SendErrorFilter - Error during filtering
[blah blah stacktrace many lines omitted]
Caused by: org.springframework.security.authentication.BadCredentialsException: Cannot obtain valid access token
at org.springframework.cloud.security.oauth2.proxy.OAuth2TokenRelayFilter.getAccessToken(OAuth2TokenRelayFilter.java:99)
at org.springframework.cloud.security.oauth2.proxy.OAuth2TokenRelayFilter.run(OAuth2TokenRelayFilter.java:79)
at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112)
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:193)
... 106 common frames omitted
在验证(UAA)服务端我可以看到zuul客户端(waharoa)一uthenticate,得到正确的用户的详细信息,然后打印:
17:12:37.288 DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
我相信这意味着,auth服务器已经做了什么,它需要和作出答复的?它看起来像Zuul服务上没有正确设置,有什么建议吗?
有人请告知我需要在这里发布什么其他信息来找出令牌刷新不起作用的原因。我是一个春天的云noob和这个公约黑魔法是不是很清楚(我已经搜索和搜索的例子,我认为是一个常见的用例,但什么都没有发现)。
注2:我已经有以下豆在Zuul侧
@Bean
public OAuth2RestTemplate oauth2RestTemplate(OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context) {
return new OAuth2RestTemplate(resource, context);
}
继@AlexK意见,我还增加了以下的UserDetailsService豆在验证方面
@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
,并补充说到我的auth服务器配置
@Autowired
private UserDetailsService userDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtTokenEnhancer())
.authenticationManager(authenticationManager).userDetailsService(userDetailsService)
.reuseRefreshTokens(false);
}
但结果相同。 refresh_token发生,但是当响应进入Zuul过滤器时它似乎仍然死亡。
注3:
@AlexK实际上是当场上。我发现学到的是,当令牌刷新时,它不仅从令牌存储刷新,而且需要调用底层的UserDetailsService来再次获取用户详细信息。当我从Active Directory获得详细信息时,这需要大量的试验和错误来解决,但现在正在按照广告方式工作。我的(缺失),简单的UserDetailsService豆如图注2这是自动连接到配置:
@Bean(name = "ldapUserDetailsService")
public UserDetailsService userDetailsService() {
FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch(searchBase, "(sAMAccountName={0})",
contextSource());
LdapUserDetailsService result = new LdapUserDetailsService(userSearch);
result.setUserDetailsMapper(new InetOrgPersonContextMapper());
return result;
}
谢谢您的答复。我已经在Zuul方面有OAuth2RestTemplate。我注意到auth中没有UserDetailsService的INFO,所以我按照你的链接添加了这个信息。不幸的是我仍然得到相同的结果。刷新)令牌过程似乎正常工作,但Zuul过滤器仍然会抛出异常。我仍然不知道这是为什么。 – LukeM
你现场点亮。我的UserDetailsService出现问题。 – LukeM
恭喜!也许未来的读者可能会对UserDetailsService的问题有所了解。我也很感兴趣 – AlexK