在微服務架構中,請求的攔截在gateway中完成,而權限的查詢是在uaa中完成,在gateway和uaa集成部署的狀況下實現較爲簡單,若是二者分離實現起來就會比較麻煩,一種方案是在gateway的資源filter中內部調用uaa的權限查詢模塊,該方案是可行的,可是存在兩個弊端:html
所以應尋找一種低響應延時、鬆散依賴的解決方案:「token擴展」。前端
"token擴展"的思路爲在token造成時追加用戶資源權限(ar)屬性,在資源的攔截中獲取ar並與當前請求的資源比對,至關於將用戶的資源權限緩存到了token中,uaa經過客戶端瀏覽器將權限信息傳遞至gateway,gateway直接解析request獲取AR,避免了內部調用致使的過分依賴問題和相應延時問題。此方案應注意在用戶登陸期間的AR變更需在下次登陸後方能生效!!!spring
具體步驟以下:後端
{...,"ar":["a.html","b.html"]}
//解析ar Cookie accessTokenCookie = OAuth2CookieHelper.getAccessTokenCookie(request); Map<String, Object> additionalInformation = tokenStore.readAccessToken(accessTokenCookie.getValue()) .getAdditionalInformation(); List<String> ar = (List<String>) additionalInformation.get("ar"); //鑑權 for (String resourceUrl : ar) { if (resourceUrl == null) { continue; } if (resourceUrl.startsWith(requestUri)) { return false; } }
org.springframework.security.oauth2.provider.token.TokenEnhancer#enhance提供了擴展token屬性的可能性,如下demo在token中增長ar屬性,並使用@Component注入容器以生效。api
@Component public class ArTokenEnhancer implements TokenEnhancer { @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { addClaims((DefaultOAuth2AccessToken) accessToken,authentication); return accessToken; } private void addClaims(DefaultOAuth2AccessToken token, OAuth2Authentication authentication) { Map<String, Object> additionalInformation = token.getAdditionalInformation(); additionalInformation.put("ar", "something you like"); token.setAdditionalInformation(additionalInformation); } }