keycloak + spring adapter + spring security反向代理重定向到root

时间:2018-01-12 17:29:36

标签: apache spring-security reverse-proxy keycloak proxypass

我们一直在使用 Apache 2.2反向代理在同一个虚拟机上运行多个应用。一切正常,直到我们添加 Keycloak适配器3.4.0.Final + spring security 1.5.9.RELEASE

这就是它的工作原理:

VM1 APP1 APP2

VM2 Keycloak

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

方案: 1)笔记本电脑 - VM2与应用程序之间的一切正常。 2)浏览器笔记本电脑之间的一切正常 - VM1 - VM2当没有反向代理时(因此直接访问应用程序端口)。 3)反向代理到位时的问题。浏览器笔记本电脑 - VM1(带有mod_prox的Apache) - 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/$1
ProxyPassReverse  ^/MyAPP/(.+) http://localhost:8585/MyAPP/$1
ProxyPreserveHost On

观察到的: 获取VM1 / MyAPP / index.html - &gt;使用正确的重定向网址重定向到VM2 keycloak 获取VM1 / MyAPP / index.html?状态= xxxx - &gt;重定向到/ GET / - &gt;根本没什么,所以它会在这里结束

首先改变: 我已经看到,这是一个关键隐藏成功处理程序,将我重定向到root。 所以我改变了它,将其重定向到同一页面:

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
....

无限循环。我还注意到应用程序每次都在进行身份验证。 可疑。

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

下一步是调试不同的请求:Proxied vs non Proxied

VM1/MyAPP vs VM1:8585/MyAPP

所以我发现每次请求都有授权头时它会对请求进行身份验证。这只发生在代理版本中。

因此,使用apache 2.2,您无法删除标头。这只是在2.4上添加的 所以再次haproxy,并尝试以相同的方式强制删除授权标头。它几乎奏效了。我遇到的问题是请求方法为1而不是GET。奇...

如此长的故事简短现在显而易见,基本认证就是问题。

如何解决这个问题?

更新

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

1 个答案:

答案 0 :(得分:0)

我是如何解决问题的:

1)因此,第一步是禁用apache上的干扰密钥泄露授权过程或至少使用Spring安全性的基本身份验证。

在此之后我开始注意到我总是被重定向到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或者只是被重定向到root。 尝试使用隐身模式后,我发现它确实有效。 尝试了不同的浏览器,它也运行良好。

3)我的浏览器仍然存在一些旧会话状态,因此清除了所有cookie关闭了所有浏览器标签并重新启动了chrome并开始工作。

4)子弹点2有一个很大的缺陷。它不允许您在同一服务器中拥有多个keycloak适配器应用程序。要改变弹簧侧的行为,我用两个过程解决它。   - 第一个是在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登录添加重定向重写规则 keycloak:   redirect-rewrite-rules:         &#34; ^ / sso / login(。*)$&#34;:&#34; / MYSUBCONTEXT / sso / login $ 1&#34;