keycloak + spring 适配器 +spring 安全反向代理重定向到 root

keycloak + spring adapter +spring security reverse proxy redirecting to root

我们一直在使用 Apache 2.2 反向代理在同一个虚拟机上运行多个应用程序 运行。在我们添加 Keycloak adapter 3.4.0.Final + spring security 1.5.9.RELEASE[=66= 之前一切正常].

这就是它的工作原理:

VM1 应用程序1 app2

VM2 钥匙斗篷

同一网络上的笔记本电脑 浏览器 app1 - 用于开发目的

场景: 1) 笔记本电脑 - VM2 与应用程序之间一切正常。 2)当没有反向代理(因此直接访问应用程序端口)时,浏览器笔记本电脑 - VM1 - VM2 之间一切正常。 3)反向代理到位时出现问题。浏览器笔记本电脑 - VM1(Apache mod_prox) - VM2

我遵循了文档中的所有建议:

http://www.keycloak.org/docs/1.9/server_installation_guide/topics/clustering/load-balancer.html

http://www.keycloak.org/docs/latest/server_installation/index.html#_setting-up-a-load-balancer-or-proxy

这些是我之前的规则:

LoadModule proxy_module modules/mod_proxy.so
ProxyRequests On

<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>

ProxyPassMatch    ^/MyAPP/(.+) http://localhost:8585/MyAPP/
ProxyPassReverse  ^/MyAPP/(.+) http://localhost:8585/MyAPP/
ProxyPreserveHost On

观察到: GET VM1/MyAPP/index.html -> 使用正确的重定向 url 重定向到 VM2 keycloak GET VM1/MyAPP/index.html?State=xxxx -> 重定向到 / GET / -> root 上没有任何内容,所以它会在这里结束

第一个变化: 我已经看到这是一个将我重定向到 root 的 keycloak 成功处理程序的原因。 所以我将其更改为将其重定向到与此相同的页面:

public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean( KeycloakAuthenticationProcessingFilter filter){
    FilterRegistrationBean registrationBean = new 
    FilterRegistrationBean(filter);
    successHandler = new AuthenticationSuccessHandler();
    successHandler.setDefaultTargetUrl("/MyAPP/index.html");
    filter.setAuthenticationSuccessHandler(successHandler);
}

观察到:

GET VM1/MyAPP/index.html -> redirected to VM2 keycloak with the right redirect url
GET VM1/MyAPP/index.html?State=xxxx -> redirected to /MyAPP/index.html
GET VM1/MyAPP/index.html?State=xxxx -> redirected to /MyAPP/index.html
GET VM1/MyAPP/index.html?State=xxxx -> redirected to /MyAPP/index.html
GET VM1/MyAPP/index.html?State=xxxx -> redirected to /MyAPP/index.html
GET VM1/MyAPP/index.html?State=xxxx -> redirected to /MyAPP/index.html
GET VM1/MyAPP/index.html?State=xxxx -> redirected to /MyAPP/index.html
....

Infinite loop.I 还注意到该应用程序每次都在进行身份验证。 可疑的。

所以我开始怀疑是 apache 导致了问题,并决定尝试使用不同的代理: haproxy。 它因同样的问题而失败。 但是我被重定向到 /sso/login intead

所以下一步是调试不同的请求:代理与非代理

VM1/MyAPP vs VM1:8585/MyAPP

所以我发现每次请求获得授权时它都会对请求进行身份验证 header.This 仅在代理版本中发生。

因此,对于 apache 2.2,您无法删除 headers。那是刚刚在 2.4 上添加的 于是又haproxy了,同样的方法试了强制取消授权header。它几乎奏效了。我遇到了一些问题,请求方法是 1 而不是 GET。奇...

长话短说现在很明显基本身份验证是问题所在。

如何解决这个问题?

更新:

我现在的问题是: 如何更改 KeycloakAuthenticationEntryPoint loginUri 以在配置中包含我的反向代理的子上下文? - 在 root 上有一个反向代理 "sso/login" 不会让我在同一台服务器上有超过 1 个 keycloak 应用程序。

我是怎么解决问题的:

1) 因此,第一步是在干扰 keycloak 授权过程或至少 spring 安全性的 apache 上禁用基本身份验证。

此后我开始注意到我总是被重定向到 root 上的 /sso/login。

2) 为了解决这个问题,我添加了一个新的代理传递规则来将 sso/login 请求重定向到我的服务器。

ProxyPassMatch ^/sso/login(.*) http://localhost:8585/sso/login$1

ProxyPassReverse ^/sso/login(.*) http://localhost:8585/sso/login$1

在此之后我仍然被重定向到 /sso/login 或者只是到根目录。 在尝试使用隐身模式后,我发现它确实有效。 尝试了不同的浏览器,它也能正常工作。

3) 一些旧的会话状态仍在我的浏览器上,因此清除所有 cookie 关闭所有浏览器选项卡并重新启动 chrome 它开始工作。

4)要点2有很大的缺陷。它不允许您在同一台服务器上拥有多个 keycloak 适配器应用程序。为了改变 spring 端的行为,我用两个过程解决了它。 - 第一个是在 keycloakAuthenticationEntryPoint

上重新设置登录 uri
    @Autowired
    AdapterDeploymentContext adapterDeploymentContext;
    private static final String OAUTH_LOGIN_URL = "/sso/login";
     @Override
    protected void configure(HttpSecurity http) throws Exception{
       KeycloakAuthenticationEntryPoint keycloakAuthenticationEntryPoint =
       new KeycloakAuthenticationEntryPoint(adapterDeploymentContext);
       keycloakAuthenticationEntryPoint.setLoginUri(realSubContext + OAUTH_LOGIN_URL);
       ...
    }

第二个是为sso登录添加重定向重写规则 钥匙斗篷: 重定向重写规则: "^/sso/login(.*)$": "/MYSUBCONTEXT/sso/login$1"