Keycloak - 弹出窗口中的外部 IDP

Bob*_*das 0 openid-connect keycloak

我在 iframe 中使用 keycloak。在我的钥匙斗篷后面是一些二级 IDP,例如 google 和 facebook。

根据我当前的配置,keycloak 只是重定向到那些辅助 IDP。这意味着它们也在 iframe 中打开。我真的很想改变这一点,因为它与我的一些主要安全政策相矛盾。

我可以以某种方式告诉 keycloak 在弹出窗口中打开外部 IDP 吗?我已阅读 keycloak“服务器管理指南”,但找不到任何有关此问题的信息。

Bob*_*das 6

好的,我找到了一个涉及大量 js hack 的解决方法。

1.

我将登录主题的login.ftl更改为不仅仅是社交提供商的href,而是执行一些js。所以之前是这样的:

<a href="${p.loginUrl}" id="zocial-${p.alias}" class="zocial ${p.providerId}">
Run Code Online (Sandbox Code Playgroud)

现在是这样的:

<a onclick="openInPopUp('${p.loginUrl}', '${name}')" id="zocial-${p.alias}" class="zocial ${p.providerId}">
<form id="kc_social_continue" method="post">
</form>
<script>
  function openInPopUp(url, name) {
    let popup = window.open(url, name, 'toolbar=no,width=600,height=600');
    let receiveMessage = (event) => {
      if (event.origin !== (window.location.protocol + '//' + window.location.hostname)){
        return;
      }
      document.forms['kc_social_continue'].action = event.data;
      document.forms['kc_social_continue'].submit();
    };
    window.addEventListener('message', receiveMessage, false);
  }
</script>
Run Code Online (Sandbox Code Playgroud)

它的作用是在弹出窗口中打开身份提供者。

此外,还注册了一个消息侦听器,该侦听器需要 URL 作为消息正文。每当收到消息时,都会将一个空表单发布到相应的 URL。

2.

添加自定义身份验证 SPI。这只是向用户呈现一个自定义的 freemarker 模板。

public class ClosePopupAuthenticator implements Authenticator {
    @Override
    public void authenticate(AuthenticationFlowContext context) {
        Response challenge = context.form().createForm("close-popup.ftl");
        context.challenge(challenge);
    }
    @Override
    public void action(AuthenticationFlowContext context) {
        context.success();
    }
}
Run Code Online (Sandbox Code Playgroud)

此 close-popup.ftl 将其 loginAction-URL 发送到父窗口,然后自行关闭。

<script>
  let host = window.location.hostname;
  let protocol = window.location.protocol;
  window.opener.postMessage("${url.loginAction}", protocol + '//' + host);
  window.close();
</script>
Run Code Online (Sandbox Code Playgroud)

3.

将此新 SPI 添加到新流程,并将该流程设置为所有相关身份提供商的“登录后流程”。