Keycloak重定向URI向端口添加端口0

时间:2018-07-01 07:23:00

标签: reverse-proxy keycloak wildfly-10 undertow wildfly-11

在密钥斗篷中遇到了redirect_uri错误。发现在JIRA KEYCLOAK-7237上记录了相同的问题,是否只想检查是否可以解决?有人可以帮忙吗?预先谢谢你。

2018-06-30 11:34:13,996警告[org.keycloak.events](默认任务8),类型= LOGIN_ERROR,realmId = Victz,clientId = portal,userId = null,ipAddress =,error = invalid_redirect_uri, redirect_uri = https://www.example.com:0/home

我正在使用在centos7(疯狂地是10,密钥斗篷3.4.3)上运行的apache http反向代理。也曾在以下环境中尝试过,但存在相同的错误。

尝试过 疯狂地10,疯狂地11,jboss 7.1, Keycloak 3.4.3和K​​eycloak 4.0

还尝试了关闭apache http并直接访问http://www.example.org:8080/home,但似乎return_uri已自动通过端口0转换为https。

请参阅以下standalone.xml,尝试在proxy-peer和request-dumper配置下删除,但没有运气。

    <subsystem xmlns="urn:jboss:domain:undertow:4.0">
        <buffer-cache name="default"/>
        <server name="default-server">
            <http-listener name="default" socket-binding="http" proxy-address-forwarding="true" enable-http2="true"/>
            <https-listener name="https" socket-binding="https" proxy-address-forwarding="true" security-realm="ApplicationRealm" enable-http2="true"/>
            <host name="default-host" alias="localhost">
                <location name="/" handler="welcome-content"/>
                <location name="/drive" handler="drive"/>
                <access-log pattern="%h %l %u %t &quot;%r&quot; %s %b &quot;%{i,Referer}&quot; &quot;%{i,User-Agent}&quot; &quot;%{i,COOKIE}&quot; &quot;%{o,SET-COOKIE}&quot; %S &quot;%I %T&quot;" prefix="access."/>
                <filter-ref name="server-header"/>
                <filter-ref name="x-powered-by-header"/>
                <http-invoker security-realm="ApplicationRealm"/>
            </host>
            <host name="example1" alias="example.com1,www.example.com1" default-web-module=“example1-0.1.war">
                <location name="/drive" handler="drive”/>
                <filter-ref name="proxy-peer"/>
                <filter-ref name="request-dumper" priority="30"/>
            </host>
            <host name="example2" alias="example.com2,www.example.com2" default-web-module="example2-0.1.war">
                <location name="/drive" handler="drive"/>
                <filter-ref name="proxy-peer"/>
                <filter-ref name="request-dumper" priority="30"/>
            </host>
            <host name="example3" alias="example.com3,www.example.com3" default-web-module="example3-0.1.war">
                <location name="/drive" handler="drive"/>
                <filter-ref name="proxy-peer"/>
                <filter-ref name="request-dumper" priority="30"/>
            </host>

        </server>
        <servlet-container name="default">
            <jsp-config/>
            <websockets/>
        </servlet-container>
        <handlers>
            <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
            <file name="drive" path="/app/drive"/>
        </handlers>
        <filters>
            <response-header name="server-header" header-name="Server" header-value="JBoss-EAP/7"/>
            <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
            <filter name="proxy-peer" class-name="io.undertow.server.handlers.ProxyPeerAddressHandler" module="io.undertow.core"/>
            <filter name="request-dumper" class-name="io.undertow.server.handlers.RequestDumpingHandler" module="io.undertow.core"/>
        </filters>
    </subsystem>

2 个答案:

答案 0 :(得分:2)

背景

在反向代理后面使用 Keycloak 的 Spring Boot client adapter 时,OAuthRequestAuthenticator.java 设置的 URL 查询参数 redirect_uri 可能由于配置不完整或错误而包含端口后缀 :0。< /p>

基本问题

为了构建 redirect_uri,Spring Boot 应用程序需要猜测其公共 URL,至少包括协议和主机名,可能还包括 IP 端口。在反向代理背后,这需要与代理合作,和/或显式配置。

:0 的解释

:0,如果存在,可能是由 OAuthRequestAuthenticator.java 设置的(这种松散的处理可能被认为是一个错误,但在目前的情况下源于不完整的配置。):Keycloak 认识到 Spring Boot应用程序正在谈论HTTPS,但没有发现HTTPS端口配置,因此默认为零。

解决步骤

假设:

  • 这是一个 Spring Boot 应用程序
  • 在反向代理后面运行
  • 充当 Keycloak 客户端

您需要确保以下几点来解决问题:

  1. 配置反向代理以添加以下标头
    • x-forwarded-for 告诉主机名
    • x-forwarded-proto 判断连接是否安全
  2. 配置 Spring Boot 应用程序以使其正确运行
  3. 配置Keycloak's Spring Boot adapter
    • 也许您需要将 confidential-port 显式设置为 443

故障排除/交叉检查

只有一点:假设这是关于反向代理背后的 Spring Boot 应用程序,您应该能够使用 tcpdump 或类似工具来监控未加密的流量(如 -i lo -s0 -A)并查看HTTP 标头。发送到 Spring Boot 应用程序的任何请求都应具有上述 Spring Boot Security How-to 所需的标头(x-forwarded-forx-forwarded-proto),否则代理配置错误。

答案 1 :(得分:1)

我遇到了同样的问题。我的Spring Boot应用程序位于nginx的后面。我更新了nginx来传递x-forwarded头文件,并使用

spring boot yaml配置:

server:
  use-forward-headers: true    

keycloak:
  realm: myrealm
  public-client: true
  resource: myclient
  auth-server-url: https://sso.example.com:443/auth
  ssl-required: external
  confidential-port: 443

nginx配置:

upstream app {
   server 1.2.3.4:8042 max_fails=1 fail_timeout=60s;
   server 1.2.3.5:8042 max_fails=1 fail_timeout=60s;
}

server {
    listen 443;
    server_name www.example.com;

    ...

    location / {
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;
        proxy_set_header        X-Forwarded-Host $host;
        proxy_set_header        X-Forwarded-Port   443;

        proxy_next_upstream     error timeout invalid_header http_500;
        proxy_connect_timeout   2;

        proxy_pass          http://app;
    }
}

使它对我有用的特定更改是添加keycloak.confidential-port。添加完之后,它将不再在redirect_uri中添加端口0。

希望有帮助。