我们一直在使用 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
以前是我的规则:
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应用程序。
答案 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;