[英]Keycloak behind apache reverse proxy
我在谷歌上瀏覽過,沒有找到任何具體的答案或例子,所以再次在這里碰碰運氣(通常很幸運)。
問題
我有一個在 apache 反向代理后面運行的 Spring Boot RESTful 服務。 此 RESTful 服務僅運行 HTTP。 假設它在本地 ip 172.s 端口 8080 上運行。
我還配置了一個 apache 反向代理。 假設它在本地 ip 172.a 和公共 ip 55.a 上運行。 此代理同時響應 80 端口,但所有 HTTP 流量都會自動重定向到 443。
我有另一台服務器運行獨立的 Keycloak 服務器。 此外,此服務器配置為可通過反向代理公開訪問。 假設它在本地 ip 172.k 上運行。 此 Keycloak 服務器僅在 HTTP 上運行。 HTTP 請求是通過反向代理使用 SSL 處理的。
最后,我在本地 ip 172.f 上運行了另一個前端 webapp。 這個frontend-webapp是在Nodejs下運行的,也是通過反向代理配置的。 它也只運行 HTTP,但客戶端(瀏覽器)通過反向代理使用 SSL,就像 Keycloak 和 RESTful 服務一樣。 該前端使用 RESTful 服務,並且還配置為使用 keycloak javascript 適配器進行身份驗證。
RESTful 服務使用 Spring Boot Keycloak 適配器配置為僅承載,而前端應用程序配置為訪問類型 public。
RESTful 服務服務器、Keycloak 服務器和前端服務器不可公開訪問; 它們只能通過反向代理訪問。 但是它們可以相互通信(因為它們在同一個專用網絡中)。
在前端keycloak.json文件中, auth-server-url
設置為代理url https://example.com/auth
,前端能夠成功獲取到一個有效的token。 現在,當我嘗試使用 RESTful 服務時,我在 RESTful 適配器中收到一個錯誤,即令牌頒發者無效。 當然,在 http-header 中,我發送的是Authorization: Bearer <token>
。 我收到此錯誤的原因是在 RESTful keycloak 配置中,我已將auth-server-url
配置為使用本地 url http://172.k:9080/auth
,因此此 url 與令牌(即https://example.com/auth
)。
題
我不能在 RESTful 服務中包含與前端相同的auth-server-url
,因為這將要求我還在 RESTful 服務上設置 HTTPs(因為該 url 是 https),這會使事情復雜化很多,包括需要設置證書之類的東西。 此外,我認為在僅本地服務器上設置 SSL 效率低下且不切實際。
所以我的問題是如何讓適配器在不通過反向代理的情況下與 Keycloak 通信。 我希望 RESTful 適配器通過auth-server-url: http://172.k:9080/auth
與 Keyclok 服務器通信以進行令牌驗證auth-server-url: http://172.k:9080/auth
。
早些時候有一個不同的后端網址,被刪除了: https : //issues.jboss.org/browse/KEYCLOAK-2623
我正在將 Keycloak 用於 docker 容器中的一個項目。 我有同樣的問題,但在本地網絡中(所以也許這不是解決方案,在這種情況下我很抱歉)。 所以情況是這樣的:
Apache 在 Docker 之外的我的機器上本地運行,提供 angular 2 應用程序,並具有正確的配置
angular 2 應用程序的適配器指向 url http://aaa.auth.com (我用條目 127.0.0.1 aaa.auth.com 修改了本地文件主機)
與您的案例(Docker、HTTP 與 HTTPS 等)有很多不同之處,但是,為了避免通過 Web 進行 REST-Keycloak 通信,您是否嘗試修改服務器的文件主機(托管 RESTful 服務)插入一個條目您的反向代理 (172.a) 和“example.com”的本地 IP?
或者,也許您可以使用私有 DNS 解決它?
我嘗試了不同的東西,但無法解決問題。 對我來說,似乎沒有辦法在后端適配器中指定auth-server-url: http://172.k:9080/auth
而前端適配器正在放置auth-server-url:https://example.com/auth
在令牌中。 所以我的解決方案是將所有后端服務也配置為auth-server-url: https://example.com/auth
。
唯一的缺點是我的后端服務適配器通過 web 與 keycloak 通信,這可能不是很好的性能明智的,但至少一切正常。 應該可以在同一本地網絡或 AWS 中的同一 VPN 中以某種方式指定本地 keycloak 端點。
您需要將反向代理的位置告知 keycloak。 然后在它的響應中,它會將 location 設置為那里而不是它的本地地址。 要在最新的 keycloak 中執行此操作,請將環境變量 'KEYCLOAK_FRONTEND_URL' 設置為指向字符串https://example.com/auth
(是的,它需要整個地址。要使其正常工作,還將PROXY_ADDRESS_FORWARDING
設置為值true
如果是 Docker 容器,則意味着:
environment:
...
PROXY_ADDRESS_FORWARDING: "true"
KEYCLOAK_FRONTEND_URL: "https://example.com/auth"
或者,您可以將KEYCLOAK_HOSTNAME
設置為example.com
,這將保留端口號,為此???(不確定如何執行此部分,如果您發現請告訴我...))
編輯:請注意,在某些情況下,您可能只想為特定客戶端設置此項。 從 keycloak 內部配置每個客戶端時,您可以從第一個選項選項卡設置它的 Frontend_URL。
我在 docker swarm 環境中遇到過類似的問題。 我的 Keycloak 和 Spring Boot 容器都在同一個反向代理后面。
對於 Tomcat:問題是正確配置 http(s) 連接器。 假設我們的反向代理的主機名和端口是 http://${EXTERNAL_HOSTNAME}:${EXTERNAL_PORT}。
然后 tomcat.xml 中的 http(s) 連接器應該有這兩個附加屬性:
<Connector [...] proxyName="${EXTERNAL_HOSTNAME}" proxyPort="${EXTERNAL_PORT}"/>
這將使所有對 servletRequest.getServerName() 和 servletRequest.getServerPort() 的調用以我們的反向代理的值進行響應。 keycloak 適配器當然使用這些函數來確定重定向 url。
對於 Spring Boot:在你的類路徑中刪除這個類:
@Component
public class TomcatReverseProxyCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, TomcatConnectorCustomizer {
@Value("${server.tomcat.proxy-name}")
private String proxyName;
@Value("${server.tomcat.proxy-port}")
private int proxyPort;
@Override
public void customize(final TomcatServletWebServerFactory factory) {
factory.addConnectorCustomizers(this);
}
@Override
public void customize(final Connector connector) {
connector.setProxyName(this.proxyName);
connector.setProxyPort(this.proxyPort);
}
}
然后在 application.properties 中設置:
server.tomcat.proxy-name=${EXTERNAL_HOSTNAME}
server.tomcat.proxy-port=${EXTERNAL_PORT}
keycloak 適配器的其他配置(示例適用於 Spring Boot):
我的 keycloak 也在同一個反向代理后面。 所以我還必須將 keycloak 適配器的身份驗證服務器 url 設置為反向代理的主機名。 然后我濫用了 keycloak 適配器的代理設置,使其使用內部分支上的服務:
keycloak.auth-server-url=http://${EXTERNAL_HOSTNAME}:${EXTERNAL_PORT}/auth
keycloak.proxy-url=http://${INTERNAL_KEYCLOAK_HOSTNAME}:${INTERNAL_KEYCLOAK_PORT}/auth
這些設置也可能有意義:
server.servlet.session.cookie.domain=${EXTERNAL_HOSTNAME}
server.use-forward-headers=true
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
server.tomcat.protocol-header 對於那些在反向代理上終止 SSL 的人很重要。
解決方案之一是將適配器升級到 8.0.0。 這個問題似乎在 8.0.0 版本中得到修復。
已知問題KEYCLOAK-6073 :
向 Java 適配器添加對 OpenID Connect Discovery 的支持...適配器應支持對前端和后端請求使用不同的 URL。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.