apache反向代理背后的Keycloak

时间:2017-02-20 10:40:52

标签: reverse-proxy keycloak

我在没有找到任何具体答案或示例的情况下浏览谷歌,所以再次在这里试试运气(通常很幸运)。

问题

  • 我在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

5 个答案:

答案 0 :(得分:3)

我在Docker容器中使用Keycloak进行项目。我有同样的问题,但在本地网络(所以这可能不是解决方案,在这种情况下,我很抱歉)。所以情况就是这样:

  • 在一个Docker容器中在wildfly上运行的REST java webapp
  • Keycloak在前一个
  • 的同一网络中的单个Docker容器中运行
  • Apache在Docker外部的机器上本地运行,提供有角度的2应用程序,配置正确

  • angular 2应用程序的适配器指向网址http://aaa.auth.com(我修改了本地文件主机,条目为127.0.0.1 aaa.auth.com)

  • 我通过主机名http://aaa.auth.com在Wildfly Docker和Keycloak Docker之间添加了一个链接,我在Java webapp适配器中使用了这个主机名。
  • 两个适配器都指向同一个地址,据我所知这是Keycloak的要求,请参阅https://issues.jboss.org/browse/KEYCLOAK-2067

与您的案例(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,这将留下端口号,为此???(尚不知道如何做这部分,如果发现,请告诉我...))