简体   繁体   English

重定向 SAML 后 Session 丢失:可能是不同的 webapps?

[英]Session lost after redirect SAML: may be different webapps?

I am fairly new to webapps programming, so I thought of asking here.我对 webapps 编程还很陌生,所以我想在这里问问。

I am implementing the SAML2 protocol in an open source app (namely OFBiz) but I am encountering a problem related to session loss after the protocol made its course.我在开源应用程序(即 OFBiz)中实施 SAML2 协议,但在协议完成后我遇到了与 session 丢失相关的问题。

I am following these steps to implement the protocol.我正在按照这些步骤来实施该协议。 Suppose ofbizwebsite.com is the URL of the site.假设ofbizwebsite.com是该站点的URL。

  1. Installed a custom plugin named SAMLIntegration which exposes the ACS page and the logic for login.安装了一个名为SAMLIntegration的自定义插件,它公开了 ACS 页面和登录逻辑。 To my understanding, a plugin (gradle) is like an indipendent java project, which translates to a new set of resources for the application (the plugin enables, for example, to visit ofbizwebsite.com/SAMLIntegration and setup some resources).据我了解,插件 (gradle) 就像一个独立的 java 项目,它转化为应用程序的一组新资源(例如,插件允许访问ofbizwebsite.com/SAMLIntegration并设置一些资源)。
  2. Exposed the ACS page to ofbizwebsite.com/SAMLIntegration/control/acs , as well as metadata ofbizwebsite.com/SAMLIntegration/control/metadata.jsp将 ACS 页面公开到ofbizwebsite.com/SAMLIntegration/control/acs以及元数据ofbizwebsite.com/SAMLIntegration/control/metadata.jsp
  3. Created the logic for login.创建登录逻辑。 Basically, an entity called UserLogin is saved in the session and recovered by a "checker" to understand if an user is logged in. Suppose that this checker is a HTTP WebEvent handler which can be called by any resource requiring authentication.基本上,名为UserLogin的实体保存在 session 中,并由“检查器”恢复以了解用户是否已登录。假设此检查器是一个 HTTP WebEvent 处理程序,任何需要身份验证的资源都可以调用它。

Now, the problem.现在,问题。 If redirect the user to a resource on SAMLIntegration (for example ofbizwebsite.com/SAMLIntegration/control/aview or any ofbizwebsite.com/SAMLIntegration/control/* by calling response.sendRedirect("aview") ) check works and login is preserved.如果将用户重定向到SAMLIntegration上的资源(例如ofbizwebsite.com/SAMLIntegration/control/aview或任何ofbizwebsite.com/SAMLIntegration/control/*通过调用response.sendRedirect("aview") )检查工作并保留登录。 Visiting any resource (for example ofbizwebsite.com/aplugin/control/anotherview ) by navigating the application does not preserve the session.通过导航应用程序访问任何资源(例如ofbizwebsite.com/aplugin/control/anotherview )不会保留 session。

OFBiz use internally a mechanism for preserving the userLogin between webapps, by creating an HashMap between and UUID and a UserLogin object. The UUID is passed between two different resources, appending this key to each path (so ofbizwebsite.com/aplugin/control/anotherview?externalKey=THEEFFECTIVEUUID ) OFBiz 在内部使用一种机制来保留 webapp 之间的 userLogin,通过在 UUID 和UserLogin object 之间创建一个 HashMap。UUID 在两个不同的资源之间传递,将此密钥附加到每个路径(so ofbizwebsite.com/aplugin/control/anotherview?externalKey=THEEFFECTIVEUUID )

To my understanding, changing from ofbizwebsite.com/SAMLIntegration/control/* to ofbizwebsite.com/aplugin/control/* determine a session loss.据我了解,从ofbizwebsite.com/SAMLIntegration/control/*更改为ofbizwebsite.com/aplugin/control/*确定 session 损失。 So, my idea was to replace the UUID mechanism with SAML2.所以,我的想法是用 SAML2 替换 UUID 机制。 However, I do not know how to solve this problem.但是,我不知道如何解决这个问题。

In particular, I would like to execute a SAML request each time the checker function is executed.特别是,我想在每次执行检查器 function 时执行一个 SAML 请求。 If I can't find the user in the session, a SAML request is fired.如果我在 session 中找不到用户,则会触发 SAML 请求。 However, my problem is HOW to manage the response.但是,我的问题是如何管理响应。 Normally, I would redirect it to the acs ofbizwebsite.com/SAMLIntegration/control/acs .通常,我会将其重定向到 acs ofbizwebsite.com/SAMLIntegration/control/acs Doing so, however, does not allow me to handle the response in the checker function, as the control is passed to another servlet by an external request (the SAML response fired by the IdP).但是,这样做不允许我处理检查器 function 中的响应,因为控制通过外部请求(IdP 触发的 SAML 响应)传递给另一个 servlet。 Should I provide a different acs for each different path?我应该为每个不同的路径提供不同的 acs 吗? (so one for SAMLIntegration and one for aplugin ?) And, even if this was the case, how can I return the control to the checker function which has invoked the SAML request? (所以一个用于SAMLIntegration ,一个用于aplugin ?)而且,即使是这种情况,我如何将控制返回给调用 SAML 请求的检查器 function?

Here you go for installing the Shibboleth HTTPD module: https://pad.nereide.fr/SAMLWithShibboleth在这里,您 go 用于安装 Shibboleth HTTPD 模块: https://pad.nereide.fr/SAMLWithShibboleth

You also need this method somewhere in OFBiz (I recommend LoginWorker.java, but you can put it where you want).您还需要在 OFBiz 的某处使用此方法(我推荐 LoginWorker.java,但您可以将其放在您想要的位置)。 It allows to use the externalAuthId of the userLogin for authentication, with the uid returned by the sso:它允许使用 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";
    }

You also need to have this method as an OFBiz preprocessor in the webapp controllers.您还需要将此方法作为 Web 应用程序控制器中的 OFBiz 预处理器。 I suggest to have a look at common-controller.xml.我建议看看 common-controller.xml。

Finally you need the configs that redirect to the SSO page if no session. That should do the job, at least it works for them...最后,如果没有 session,您需要重定向到 SSO 页面的配置。这应该可以完成工作,至少对他们有用……

Finally I recommend https://www.varonis.com/blog/what-is-saml in case of need.最后我推荐https://www.varonis.com/blog/what-is-saml以备不时之需。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM