keycloak + spring 适配器 +spring security 反向代理重定向到root
Posted
技术标签:
【中文标题】keycloak + spring 适配器 +spring security 反向代理重定向到root【英文标题】:keycloak + spring adapter +spring security reverse proxy redirecting to root 【发布时间】:2018-06-22 05:04:40 【问题描述】:我们一直在使用 Apache 2.2 反向代理让多个应用程序在同一个 VM 上运行。在我们添加 Keycloak 适配器 3.4.0.Final + spring security 1.5.9.RELEASE 之前,一切正常。
这就是它的工作原理:
VM1 应用程序1 应用程序2
虚拟机2 钥匙斗篷
同一网络上的笔记本电脑 浏览器 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
观察到: GET VM1/MyAPP/index.html -> 使用正确的重定向 url 重定向到 VM2 keycloak GET VM1/MyAPP/index.html?State=xxxx -> 重定向到 / GET / -> root 上没有任何东西,所以它会在这里结束
第一个变化: 我已经看到造成这种情况的原因是 keycloak 成功处理程序将我重定向到 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 导致了问题,并决定尝试使用不同的代理: 代理服务器。 它因同样的问题而失败。 但我被重定向到 /sso/login intead
所以下一步是调试不同的请求:代理与非代理
VM1/MyAPP vs VM1:8585/MyAPP
所以我发现每次请求具有授权标头时它都会对请求进行身份验证。这只发生在代理版本中。
因此,使用 apache 2.2,您无法删除标头。刚刚添加到 2.4 所以再次使用haproxy,并以相同的方式尝试强制删除授权标头。它几乎奏效了。我遇到了一些问题,请求方法是 1 而不是 GET。奇怪...
长话短说现在很明显,基本身份验证是问题所在。
如何解决这个问题?
更新:
我现在的问题是: 如何更改 KeycloakAuthenticationEntryPoint loginUri 以在配置中包含我的反向代理的子上下文? - 在 root 上拥有反向代理“sso/login”不会让我在同一服务器上拥有超过 1 个 keycloak 应用程序。
【问题讨论】:
【参考方案1】:我是如何解决这个问题的:
1) 所以第一步是禁用干扰 keycloak 授权过程或至少干扰 spring 安全性的 apache 上的基本身份验证。
在这之后我开始注意到我总是被重定向到根目录下的 /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 适配器应用程序。为了改变弹簧侧的行为,我用两个过程来解决它。 - 第一个是在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"
【讨论】:
以上是关于keycloak + spring 适配器 +spring security 反向代理重定向到root的主要内容,如果未能解决你的问题,请参考以下文章
生成 SP 元数据时出现意外的堆栈跟踪表单 Spring-Security-SAML?
使用 Spring Security Saml 和 SP 应用程序的无状态会话
在反向代理后面使用 SP 时出现 Spring saml 问题