3

我正在配置使用Zuul反向代理實用程序的Spring Cloud(Angel.SR6)應用程序,以便隱藏內部服務端口。我的zuul(邊緣)服務在8765端口發佈,我的組織服務在8083端口。當我沒有安全地訪問應用程序時,一切都會順利進行,http://localhost:8765/organization/organizations返回所有組織的JSON。Zuul反向代理與Keycloak服務器

但是,現在我想集成一個Keycloak SSO(OAuth2)服務器用於授權目的。我在我的組織服務中添加了Spring Security adapter,並將其配置爲在http://localhost:8080/auth中進行身份驗證。一切順利,除了zuul執行重定向而不是代理。所以當身份驗證成功時,我將重定向到http://localhost:8083/organizations而不是http://localhost:8765/organization/organizations。這裏有我的瀏覽器的請求:

enter image description here

這是因爲keycloak適配器會在http://localhost:8083/sso/login令牌驗證端點,從它以驗證令牌執行重定向到授權服務器。當授權服務器確認它時,將重定向發送到組織服務,路徑爲/organization,因此加載的最終url爲http://localhost:8083/organizations。但我想要加載第一個請求的網址。

我有哪些選擇?

+0

我可以肯定的一件事是,zuul本身沒有重定向,它只轉發響應,所以如果下游服務發送重定向,zuul會將其轉發給瀏覽器。 – spencergibb

+0

@spencergibb,我知道,實際上問題在於下游服務,它有一個配置重定向到SSO服務器的登錄端點。 SSO服務器接收要重定向到的url作爲url參數,如'/ auth/realm/master?redirectUri = http:// localhost:8083/sso/login'。因此,SSO服務器執行重定向到該URL,該URL也會重定向到最終的「http:// localhost:8083/organizations」路徑。一個解決方案是隻保護zuul服務,所以我會將每個請求重定向到zuul本身,但這會涉及到將其餘服務暴露出來。 –

回答

1

最近我遇到了同樣的問題。我已經解決了它:

  1. 添加到application.properties在Zuul

    zuul.sensitive報頭=餅乾,設置Cookie

  2. 在Zuul

    介紹KeycloakFilterRoute
    class KeycloakFilterRoute extends ZuulFilter { 
    
    private static final String AUTHORIZATION_HEADER = "authorization"; 
    
    @Override 
    public String filterType() { 
        return "route"; 
    } 
    
    @Override 
    public int filterOrder() { 
        return 0; 
    } 
    
    @Override 
    public boolean shouldFilter() { 
        return true; 
    } 
    
    @Override 
    public Object run() { 
        RequestContext ctx = RequestContext.getCurrentContext(); 
        if (ctx.getRequest().getHeader(AUTHORIZATION_HEADER) == null) { 
         addKeycloakTokenToHeader(ctx); 
        } 
        return null; 
    } 
    
    private void addKeycloakTokenToHeader(RequestContext ctx) { 
        RefreshableKeycloakSecurityContext securityContext = getRefreshableKeycloakSecurityContext(ctx); 
        if (securityContext != null) { 
         ctx.addZuulRequestHeader(AUTHORIZATION_HEADER, buildBearerToken(securityContext)); 
        } 
    } 
    
    private RefreshableKeycloakSecurityContext getRefreshableKeycloakSecurityContext(RequestContext ctx) { 
        if (ctx.getRequest().getUserPrincipal() instanceof KeycloakAuthenticationToken) { 
         KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) ctx.getRequest().getUserPrincipal(); 
         return (RefreshableKeycloakSecurityContext) token.getCredentials(); 
        } 
        return null; 
    } 
    
    private String buildBearerToken(RefreshableKeycloakSecurityContext securityContext) { 
        return "Bearer " + securityContext.getTokenString(); 
    } 
    

    }

+0

好的意思。爲了向keycloak團隊解釋我的問題,我最終做出了一個Github項目,並得到了一位開發團隊成員試圖幫助我的請求。這裏你有[鏈接](https://github.com/xtremebiker/zuul-keycloak-test/pull/1),它可能對你有用。根據他們的建議,我得出的結論是zuul很好地隱藏無狀態服務(只有持有者),但不是用戶直接與之交互的服務。這裏是郵件列表中的[整個主題](http://lists.jboss.org/pipermail/keycloak-user/2016-May/006287.html)。 –

相關問題