我有一個使用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