热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

KeycloakSAML注销问题

我们正在研究一个需要SAMLSSO的项目,因此我们决定使用keycloak进行此实现。用例

我们正在研究一个需要SAML SSO的项目,因此我们决定使用keycloak进行此实现。

用例


  • 具有外部IdP的SSO-密钥隐藏代理


    • SP启动和IdP启动登录



  • 将Keycloak作为IdP的SSO-使用keycloak服务器进行注册和用户管理

基本设置


  • Keycloak服务器版本
    4.8.3。最终


  • Wildfly版本
    10.1.0。最终


  • Wildfly适配器版本
    keycloak-saml-wildfly-adapter-dist-4.8.3.Final


我们还将Nginx用作独立Wildfly服务器之前的代理。

与密钥斗篷相关的nginx配置:

location ^~ /auth/ {
proxy_pass http://localhost:8180/auth/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
}

部署架构

我们部署了一个耳朵,其中包含常见的jar和部署描述符(如jboss-deployment-structure.xml)。
该耳朵还包含一个war文件,其中包含用于客户端配置的jboss-web.xml和keycloak-saml.xml。
在以下示例中,它还包含多个jar,例如auth.login.saml.web.jar。
战争本身有一个web.xml,而lib文件夹中的jar有web-fragment.xml文件。

app.ear
├── Meta-INF
│ ├── application.xml
│ ├── jboss-app.xml
│ ├── jboss-classloading.xml
│ ├── jboss-deployment-structure.xml
│ ├── MANIFEST.MF
└── mywar.war
├── Meta-INF
│ ├── MANIFEST.MF
└── WEB-INF
├── classes
├── jboss-web.xml
├── keycloak-saml.xml
├── lib
│ └── auth.login.saml.web.jar
│ ├── at
│ │ └── prismasolutions
│ │ └── ppcf
│ │ └── core
│ │ └── auth
│ │ ├── login
│ │ └── SAMLLoginServlet.class
│ ├── Meta-INF
│ │ ├── MANIFEST.MF
│ │ └── web-fragment.xml
└── web.xml

我们有一个基于权限的底层系统,该系统需要根据Principals属性从数据库中加载角色和权限。
该主体通过Jboss-Security或Keycloak客户端适配器登录。在SamlLoginServlet中,SamlPrincipal用于提取属性并将其在应用程序中使用。

问题

两种定义的用例的登录过程似乎都可以正常工作

但是

关于注销过程,我们确实有些挣扎和未解决的问题。关于我在2019年6月发送的另一个支持请求,注销不适用于我们记录的文档:
https://lists.jboss.org/pipermail/keycloak-user/2019-June/018550.html

文档指出:

“有多种方法可以从Web应用程序注销。对于Java EE servlet容器,可以调用HttpServletRequest.logout()。对于其他任何浏览器应用程序,可以将浏览器指向Web应用程序的任何url具有安全性约束,并传入查询参数GLO,即http://myapp?GLO=true http://myapp/?GLO=true。如果您与浏览器进行SSO会话,则会注销您的登录。”

在我们的应用程序中,注销是通过调用Servlet(称为GlobalLogoutServlet)来实现的。它在战争中包含的jar中的web-fragment.xml中注册:


GlobalLogoutServlet
/login

为避免混淆:客户端中有一个指向URL / login?logout的注销按钮,这就是为什么要在URL-Path / login上进行注册的原因。

实现:

public class GlobalLogoutServlet extends HttpServlet {
private static final String LOGOUT_PARAM = "logout";
@Override
protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException {
String queryString = req.getQueryString();
if (LOGOUT_PARAM.equalsIgnoreCase(queryString)) {
requestGlobalLogout(req,resp);
}
}
private void requestGlobalLogout(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException {
AuthFacade authBean = new CommonBeanaccessorGeneric().getFacade(AuthFacade.BEAN_NAME,AuthFacade.class);
try {
authBean.logout(req,resp);
} catch (PrismaLoginException e) {
throw new ServletException(e);
}
}

如您所见,有一个对EJB(AuthFacade)的调用,它执行应用程序登录(从我们的数据库中加载角色和权限),在这种情况下,注销的实现如下:

@Override
protected void doLogout(HttpServletRequest request,HttpServletResponse response) throws PrismaLoginException {
//HttpSession session = request.getSession();
//session.invalidate();
try {
request.logout();
String ctp = getGlobalLogoutUrl(request);
response.sendRedirect(ctp);
}catch(Exception e) {
throw new PrismaLoginException(e);
}
}
private String getGlobalLogoutUrl(HttpServletRequest request) {
String ctp = request.getcontextPath();
ctp = cutTrailingSlash(ctp);
ctp = ctp + "?GLO=true";
return ctp;
}

引用https://lists.jboss.org/pipermail/keycloak-user/2018-August/015164.html对HttpServletRequest.logout()的调用不是非操作(它对SecurityContext有作用吗?),但是不会触发对IdP的LogoutRequest。
仅当我还使用queryParam“?GLO = true”调用URL时,才完成此操作。这会触发另一个AuthnRequest(WHY?),因此代理上还有另一个登录名
此后,发生以下两种情况之一:


  1. 在idp启动的登录设置中-响应发送到应用程序,并显示错误页面,其中显示“用户已登录”和“返回应用程序”的链接


    • 也永远不会发送注销请求



  2. 在sp中启动登录设置-随后出现注销请求和状态成功的注销响应,导致重定向到主服务器,处理诸如https://myapp/webcontext/saml和403 Forbidden


请帮助我确定这些问题。我已经阅读了很多相关的文章,但无法使它正常工作。

https://lists.jboss.org/pipermail/keycloak-user/2018-August/015164.html

我还给Red Hat写了一条消息,将来我们可能会订阅以获得更多支持,但他们尚未答复。

我将提供由idp启动的第三方idp登录进行设置的一些配置详细信息:

jboss-web.xml:



keycloak

战争中的web.xml:


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
myapp

resteasy.scan
true



登录模块jar的

web-fragment.xml:

xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd">
SAMLLoginFragment

GlobalLogoutServlet
at.prismasolutions.ppcf.core.auth.login.pvpsaml.GlobalLogoutServlet


GlobalLogoutServlet
/login


PublicContentServlet
at.prismasolutions.ppcf.core.common.service.PublicContentServlet


PublicContentServlet
/public/*


SAMLLoginServlet
at.prismasolutions.ppcf.core.auth.login.pvpsaml.SAMLLoginServlet


SAMLLoginServlet
/saml_login


*




The protected resources
/*


*


NONE





The unprotected resources
/public/*
/saml_login



NONE



KEYCLOAK-SAML




/



客户端keycloak-saml.xml


sslPolicy="EXTERNAL">


file="${jboss.server.config.dir}/keystore/keystore.jks"
password="*****">
alias="mykey"
password="****" />
alias="mycert" />



file="${jboss.server.config.dir}/keystore/keystore.jks"
password="*****">
alias="mykey"
password="*****" />



attribute="USERID" />
signatureCanOnicalizationmethod="http://www.w3.org/2001/10/xml-exc-c14n#">
validateRespOnseSignature="true" validateAssertiOnSignature="true"
requestBinding="POST"
bindingUrl="https://mybroker/auth/realms/MYREALM/protocol/saml" />
signRespOnse="true" validateRequestSignature="true"
validateRespOnseSignature="true" requestBinding="POST"
respOnseBinding="POST"
postBindingUrl="https://mybroker/auth/realms/MYREALM/protocol/saml"
redirectBindingUrl="https://mybroker/auth/realms/MYREALM/protocol/saml" />



standalone.xml中与Keycloak相关的摘要:







...

在第三方idp中为idp启动的设置导入的元数据:


protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol http://schemas.xmlsoap.org/ws/2003/07/secext">
urn:oasis:names:tc:SAML:2.0:nameid-format:persistent


*****

*****





*****

*****




Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://mybroker/auth/realms/MYREALM/broker/myidp/endpoint/clients/myapp"
index="1" isDefault="true" />


对于有关saml注销的任何其他信息,我将感到满意:


  • 有关任何部分中与注销相关的所有配置的信息
    系统的

  • 有关所有Keycloak类的信息注销
    过程取决于

对于解决此问题的任何帮助,我将深表感谢。请随时询问更多信息,我将竭尽所能。

非常感谢

Manuel Waltschek





推荐阅读
author-avatar
YON永世
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有