我试图从我的Web应用程序中了解反向通道注销的流程,但我发现文档令人困惑。我有一个在JBoss EAP中运行的JEE应用程序,Java Servlet Filter Adapter(由于某些技术原因,我不能使用EAP适配器)。 documentation for logging out说:
您可以通过多种方式注销Web应用程序。对于Java EE servlet容器,可以调用HttpServletRequest.logout()。对于 其他浏览器应用程序,您可以将浏览器重定向到 http://auth-server/auth/realms/ {realm-name} / protocol / openid-connect / logout?redirect_uri = encodedRedirectUri,如果您与浏览器进行SSO会话,则会将您注销。
例如,backchannel注销的工作方式是: 1.用户从一个应用程序发送注销请求 2.应用程序向Keycloak发送注销请求 3. Keycloak服务器使用户会话无效 4.然后,Keycloak服务器向应用程序发送一个反向通道请求,其中包含与该会话关联的管理URL 5.当应用程序收到注销请求时,它会使相应的HTTP会话无效
根据我的理解,要么:
http://auth-server/auth/realms/{realm-name}/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri
应该以某种方式检测clientId(来自重定向URI?)并向适当的反向通道发送请求这两种选择似乎对我都不起作用。在这两种情况下,我都没有从Keycloak回复到我的adminUrl。此外,在调用Request.logout()之后,我仍然在我的Keycloak Admin中看到相同数量的活动会话。根据{{3}},它似乎有效,但我不确定我是否缺少配置或类似的东西。
我尝试使用access_token将GET发送到注销终端,但这也没有任何区别。
我从这份文件中误解了什么?我该如何编写注销代码?
答案 0 :(得分:3)
普通注销和反向通道注销是两个完全不同的东西。
普通注销的工作原理是将浏览器重定向到您在(2)中提到的网址。用户被Keycloak中的浏览器会话识别,因此浏览器重定向至关重要(甚至不需要提供redirect_uri)。
我们在Tomcat中通过调用我们的应用程序中的以下代码实现了这一点,该代码自动触发重定向(当然,使用keycloak.json作为配置):
Object keycloakAttr = request.getAttribute(KeycloakSecurityContext.class.getName());
if (keycloakAttr != null && keycloakAttr instanceof RefreshableKeycloakSecurityContext)
{
// code inspired by org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.logoutInternal
RefreshableKeycloakSecurityContext ksc = (RefreshableKeycloakSecurityContext)keycloakAttr;
KeycloakDeployment deployment = ksc.getDeployment();
ksc.logout(deployment);
// Since a CatalinaSessionTokenStore is used as token store in Tomcat
// tokenStore.logout() is not be necessary (???)
request.removeAttribute(KeycloakSecurityContext.class.getName());
request.setUserPrincipal(null);
}
反向频道注销仅在多个依赖方(在OIDC发言中)或“客户”中的Keycloak方面才有意义。它确保同一领域(针对同一用户)的客户端的客户端会话不会在注销中“存活”。
执行上面的注销后,Keycloak会检查是否存在与Keycloak会话关联的客户端会话,并将反向通道注销请求发送到相应的客户端(在同一个域中!),因此浏览器会话根本不涉及此过程
为了使这项工作(对于Node.js和Tomcat都正确安装了相应的Keycloak适配器),我们只需要正确配置Keycloak中客户端的管理URL。注意:它默认为“/”,但对于Tomcat,必须包含webapp上下文,例如https://myapp.com/mywebapp/
答案 1 :(得分:0)
您不使用Keycloak的适配器之一吗?我遇到了完全相同的问题。
事实证明,当密钥交换交换代码时,自己的密钥斗篷适配器将if (exception is MongoBulkWriteException<T> mostRecentException)
{
var unProcessedRequests =
mostRecentException.UnprocessedRequests.ToList();
if (mostRecentException.WriteErrors.Any())
{
//get processed requests (without success) that failed and add to remainingWork
var requestWithError = new[]
{
mostRecentException.Result.ProcessedRequests[
mostRecentException.WriteErrors[0].Index]
};
unProcessedRequests = unProcessedRequests.Concat(requestWithError).ToList();
}
remainingWork = unProcessedRequests.ToList();
}
else if (exception is CosmosDbRateLimitingBugException<T> cosmosDbBug)
{
remainingWork = cosmosDbBug.UnprocessedRequests;
}
的POST发送到client_session_state
。
除非在protocol/openid-connect/token
POST中提供了这样的参数,否则不会调用AdminURL。去搞清楚。添加该参数,它将开始工作!
查看相关的keycloak forum post