[英]Session lost after redirect SAML: may be different webapps?
我對 webapps 編程還很陌生,所以我想在這里問問。
我在開源應用程序(即 OFBiz)中實施 SAML2 協議,但在協議完成后我遇到了與 session 丟失相關的問題。
我正在按照這些步驟來實施該協議。 假設ofbizwebsite.com
是該站點的URL。
SAMLIntegration
的自定義插件,它公開了 ACS 頁面和登錄邏輯。 據我了解,插件 (gradle) 就像一個獨立的 java 項目,它轉化為應用程序的一組新資源(例如,插件允許訪問ofbizwebsite.com/SAMLIntegration
並設置一些資源)。ofbizwebsite.com/SAMLIntegration/control/acs
以及元數據ofbizwebsite.com/SAMLIntegration/control/metadata.jsp
UserLogin
的實體保存在 session 中,並由“檢查器”恢復以了解用戶是否已登錄。假設此檢查器是一個 HTTP WebEvent 處理程序,任何需要身份驗證的資源都可以調用它。 現在,問題。 如果將用戶重定向到SAMLIntegration
上的資源(例如ofbizwebsite.com/SAMLIntegration/control/aview
或任何ofbizwebsite.com/SAMLIntegration/control/*
通過調用response.sendRedirect("aview")
)檢查工作並保留登錄。 通過導航應用程序訪問任何資源(例如ofbizwebsite.com/aplugin/control/anotherview
)不會保留 session。
OFBiz 在內部使用一種機制來保留 webapp 之間的 userLogin,通過在 UUID 和UserLogin
object 之間創建一個 HashMap。UUID 在兩個不同的資源之間傳遞,將此密鑰附加到每個路徑(so ofbizwebsite.com/aplugin/control/anotherview?externalKey=THEEFFECTIVEUUID
)
據我了解,從ofbizwebsite.com/SAMLIntegration/control/*
更改為ofbizwebsite.com/aplugin/control/*
確定 session 損失。 所以,我的想法是用 SAML2 替換 UUID 機制。 但是,我不知道如何解決這個問題。
特別是,我想在每次執行檢查器 function 時執行一個 SAML 請求。 如果我在 session 中找不到用戶,則會觸發 SAML 請求。 但是,我的問題是如何管理響應。 通常,我會將其重定向到 acs ofbizwebsite.com/SAMLIntegration/control/acs
。 但是,這樣做不允許我處理檢查器 function 中的響應,因為控制通過外部請求(IdP 觸發的 SAML 響應)傳遞給另一個 servlet。 我應該為每個不同的路徑提供不同的 acs 嗎? (所以一個用於SAMLIntegration
,一個用於aplugin
?)而且,即使是這種情況,我如何將控制返回給調用 SAML 請求的檢查器 function?
在這里,您 go 用於安裝 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";
}
您還需要將此方法作為 Web 應用程序控制器中的 OFBiz 預處理器。 我建議看看 common-controller.xml。
最后,如果沒有 session,您需要重定向到 SSO 頁面的配置。這應該可以完成工作,至少對他們有用……
最后我推薦https://www.varonis.com/blog/what-is-saml以備不時之需。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.