会话丢失后重定向SAML:可能是不同的web应用程序?



我对webapps编程相当陌生,所以我想在这里问一下。

我正在一个开源应用程序(即OFBiz)中实现SAML2协议,但在协议完成后,我遇到了与会话丢失相关的问题。

我遵循这些步骤来实现协议。设ofbizwebsite.com为站点的URL。

  1. 安装了一个名为SAMLIntegration的自定义插件,该插件暴露了ACS页面和登录逻辑。在我看来,一个插件(gradle)就像一个独立的java项目,它为应用程序转换了一组新的资源(例如,插件允许访问ofbizwebsite.com/SAMLIntegration并设置一些资源)。
  2. 将ACS页面暴露给ofbizwebsite.com/SAMLIntegration/control/acs,以及元数据ofbizwebsite.com/SAMLIntegration/control/metadata.jsp
  3. 创建登录逻辑。基本上,一个名为UserLogin的实体被保存在会话中,并由"检查器"恢复。了解用户是否已登录。假设这个检查器是一个HTTP WebEvent处理程序,可以被任何需要身份验证的资源调用。

问题来了。如果将用户重定向到SAMLIntegration上的资源(例如,通过调用response.sendRedirect("aview")将用户重定向到ofbizwebsite.com/SAMLIntegration/control/aview或任何ofbizwebsite.com/SAMLIntegration/control/*),则check工作并保留登录。通过导航应用程序访问任何资源(例如ofbizwebsite.com/aplugin/control/anotherview)都不会保留会话。

OFBiz在内部使用一种机制来保存webapps之间的userLogin,通过在UUID和UserLogin对象之间创建一个HashMap。UUID在两个不同的资源之间传递,将此键附加到每个路径(例如ofbizwebsite.com/aplugin/control/anotherview?externalKey=THEEFFECTIVEUUID)

根据我的理解,从ofbizwebsite.com/SAMLIntegration/control/*更改为ofbizwebsite.com/aplugin/control/*确定会话丢失。因此,我的想法是用SAML2取代UUID机制。然而,我不知道如何解决这个问题。

特别是,我想在每次执行检查器函数时执行一个SAML请求。如果在会话中找不到用户,就会触发一个SAML请求。然而,我的问题是如何管理回应。通常,我会将其重定向到acsofbizwebsite.com/SAMLIntegration/control/acs。但是,这样做不允许我在检查器函数中处理响应,因为控件通过外部请求(由IdP触发的SAML响应)传递给另一个servlet。我应该为每个不同的路径提供不同的acs吗?(一个用于SAMLIntegration,一个用于aplugin?)而且,即使是这种情况,我如何将控件返回给调用了SAML请求的检查器函数?

安装Shibboleth HTTPD模块:https://pad.nereide.fr/SAMLWithShibboleth

你也需要这个方法在OFBiz的某处(我推荐LoginWorker.java,但你可以把它放在你想要的地方)。它允许使用userLogin的externalAuthId进行身份验证,并使用sso:

返回的uid
public static String checkShibbolethRequestRemoteUserLogin(HttpServletRequest request, HttpServletResponse response) {
LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
Delegator delegator = dispatcher.getDelegator();

// make sure the user isn't already logged in
if (!LoginWorker.isUserLoggedIn(request)) {
String remoteUserId = (String) request.getAttribute("uid"); // This is the one which works, uid at Idp, remoteUserId here
if (UtilValidate.isNotEmpty(remoteUserId)) {
//we resolve if the user exist with externalAuthId
String userLoginId = null;
GenericValue userLogin;
try {
List<GenericValue> userLogins = delegator.findList("UserLogin",
EntityCondition.makeConditionMap("externalAuthId", remoteUserId, "enabled", "Y"),
null, null, null, true);
userLogin = userLogins.size() == 1 ? userLogins.get(0) : null;
} catch (GenericEntityException e) {
Debug.logError(e, module);
return "error";
}
if (userLogin != null) {
userLoginId = userLogin.getString("userLoginId");
}
//now try to log the user found
return LoginWorker.loginUserWithUserLoginId(request, response, userLoginId);
}
}
return "success";
}

你还需要在webapp控制器中将这个方法作为OFBiz预处理器。我建议看一下common-controller.xml。

最后,如果没有会话,您需要重定向到SSO页面的配置。这应该能起作用,至少对他们有用。

最后我推荐https://www.varonis.com/blog/what-is-saml,如果需要的话。

相关内容

  • 没有找到相关文章

最新更新