我曾经遇到过与keycloak v1.5.0.Final / Internet Explorer 11相同的问题,最终找出了问题所在。
1. 背后的原因
当在Keycloak的init方法中使用"login-required"或"check-sso"模式时,Keycloak Javascript适配器会设置一个iframe,定时检查用户是否已经通过身份验证。
该iframe从keycloak服务器检索而来(假设是 http(s)://yourkeycloakhost:port
):
http(s)://yourkeycloakhost:port/auth/realms/yourrealm/protocol/openid-connect/login-status-iframe.html?client_id=yourclientid&origin=http(s)://yourorigin
其内容是JavaScript脚本,可以访问由Keycloak在认证时(在相同的域名下,即http(s)://yourkeycloakhost:port
)设置的KEYCLOAK_SESSION cookie。
2. IE的问题
没错!这就是使用Internet Explorer时遇到的问题,它对iframe和cookie有严格的策略。实际上,由于其P3P政策(Microsoft Internet Explorer是仅支持P3P的主要浏览器),keycloak iframe无法访问yourkeycloakhost
域的cookie。
此问题在这个stackoverflow问题中有很好描述。
3. 解决方案
解决方案是使Internet Explorer信任我们的Keycloak域(yourkeycloakhost
)以使用cookie,以便iframe能够读取KEYCLOAK_SESSION
cookie值,并将其注册在其数据中。
为此,您的Keycloak服务器必须附加带有P3P信息的HTTP响应头。您可以使用Apache或Nginx代理来始终设置正确的标头。我使用了Apache和其mod_headers模块:
Header always set P3P "CP=ALL DSP COR CUR ADM PSA CONi OUR SAM OTR UNR LEG"
你可以通过W3C了解有关P3P的更多信息,或使用此P3P验证器验证您的P3P策略。
4. 后果
您可以查看keycloak的iframe代码:
var cookie = getCookie('KEYCLOAK_SESSION');
if (cookie) {
data.loggedIn = true;
data.session = cookie;
}
现在Internet Explorer可以正确获取域名为yourkeycloakhost
的cookie,问题已经得到解决!