我在没有找到任何具体答案或示例的情况下浏览谷歌,所以再次在这里试试运气(通常很幸运)。
问题
我在apache后面运行一个Spring启动RESTful服务 反向代理。此RESTful服务仅运行HTTP。说它正在运行 本地ip 172.s端口8080。
我还配置了一个apache反向代理。说它正在运行 本地ip 172.a和公共IP 55.a.此代理响应端口80,但所有HTTP流量自动重定向到443。
我有另一台运行独立Keycloak服务器的服务器。也 此服务器配置为可通过公共访问 反向代理。假设它在本地ip 172.k上运行。此Keycloak服务器仅在HTTP上运行。通过反向代理使用SSL处理HTTP请求。
最后,我在本地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
,前端能够成功获取有效令牌。现在,当我尝试使用RESTful服务时,我在RESTful适配器中收到令牌发布者无效的错误。在http-header中,我当然是发送Authorization: Bearer <token>
。我收到此错误的原因是,在RESTful keycloak配置中,我已将auth-server-url
配置为使用本地URL http://172.k:9080/auth
,因此此URL与令牌中的url(https://example.com/auth
不同1}})。
问题
我不能在RESTful服务中包含与前端相同的auth-server-url
,因为这将要求我在RESTful服务上设置HTTP(因为该URL是https),这将使事情复杂化很多,包括需要设置证书和类似的东西。此外,我认为在仅本地服务器上设置SSL是低效且不实际的。
所以我的问题是如何在不通过反向代理的情况下使适配器与Keycloak通信。我希望RESTful适配器通过auth-server-url: http://172.k:9080/auth
与Keyclok服务器通信以进行令牌验证。
之前有一个不同的后端网址,已删除:https://issues.jboss.org/browse/KEYCLOAK-2623
答案 0 :(得分:3)
我在Docker容器中使用Keycloak进行项目。我有同样的问题,但在本地网络(所以这可能不是解决方案,在这种情况下,我很抱歉)。所以情况就是这样:
Apache在Docker外部的机器上本地运行,提供有角度的2应用程序,配置正确
angular 2应用程序的适配器指向网址http://aaa.auth.com(我修改了本地文件主机,条目为127.0.0.1 aaa.auth.com)
与您的案例(Docker,HTTP与HTTPS等)存在很多差异,但是,为了避免通过Web进行REST-Keycloak通信,您是否尝试过修改服务器的文件主机(托管RESTful服务)具有反向代理(172.a)和&#34; example.com&#34;的本地IP的条目?
或者,也许您可以使用私有DNS来解决它?
答案 1 :(得分:2)
解决方案之一是将适配器升级到8.0.0。这个问题似乎在8.0.0版中已解决。
这是已知的问题KEYCLOAK-6073:
添加对OpenID Connect Discovery到Java适配器的支持... 适配器应支持对前端和后端请求使用不同的URL。
答案 2 :(得分:1)
我尝试了不同的东西,但无法解决问题。对我来说,当前端适配器在令牌中放置auth-server-url: http://172.k:9080/auth
时,似乎无法在后端适配器中指定auth-server-url:https://example.com/auth
。所以我的解决方案是将所有后端服务配置为auth-server-url: https://example.com/auth
。
唯一的缺点是我的后端服务适配器通过web与keycloak通信,这可能不是那么好的性能,但至少一切都按预期工作。应该可以以某种方式在同一本地网络中指定本地keycloak端点,或在AWS中指定相同的VPN。
答案 3 :(得分:1)
在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适配器的auth服务器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的人来说很重要。
答案 4 :(得分:0)
您需要告知keycloak反向代理的位置。然后,它将在响应中将位置设置为该位置,而不是其本地地址。为此,请在最新的密钥斗篷中将环境变量“ KEYCLOAK_FRONTEND_URL”设置为指向
字符串transacao
(是的,它需要整个地址。
为此,请将https://example.com/auth
设置为值PROXY_ADDRESS_FORWARDING
如果它是Docker容器,则意味着:
true
或者,您可以将environment:
...
PROXY_ADDRESS_FORWARDING: "true"
KEYCLOAK_FRONTEND_URL: "https://example.com/auth"
设置为KEYCLOAK_HOSTNAME
,这将留下端口号,为此???(尚不知道如何做这部分,如果发现,请告诉我...))