前言:在應用於集團版客戶或SAAS平臺服務的業務系統中,流程管理系統需要支持多用戶組織模型。其中包括角色數據、流程定義數據和流程實例數據的多用戶標識綁定。本文旨在全面描述如何基於SlickOne敏捷開發框架實現上述基礎服務功能,形成一個完整的支持多用戶查看和維護各自流程數據的管理後臺系統。 1. 基 ...
前言:在應用於集團版客戶或SAAS平臺服務的業務系統中,流程管理系統需要支持多用戶組織模型。其中包括角色數據、流程定義數據和流程實例數據的多用戶標識綁定。本文旨在全面描述如何基於SlickOne敏捷開發框架實現上述基礎服務功能,形成一個完整的支持多用戶查看和維護各自流程數據的管理後臺系統。
1. 基礎數據的多用戶標識
1.1 多用戶(公司)數據表
資料庫表SysCompany用來存儲多用戶/多租戶的基本信息,欄位CompanyID 用來標識後期業務數據的所有者。
1.2 角色/用戶數據表
角色用戶表統一增加CompanyID欄位,用來確定角色和用戶屬於具體的那一個用戶或租戶。
1.3. 流程定義數據的多用戶標識
資料庫表WfProcess增加CompanyID欄位,用來標識流程定義屬於那一個用戶或租戶。
1.4. 流程實例數據的多用戶標識
所有的流程實例數據,統一增加CompanyID欄位,用了標識流程實例數據的擁有者範圍。
2. 多站點類型的SSO功能實現
多站點SSO單點登錄功能的實現,便於統一整合不同子系統的數據管理和維護;尤其對於平臺級別的軟體產品,多個子系統的是需要經常頻繁操作訪問的。所以,一次登錄,再次免驗證,就非常方便簡捷。
2.1 系統環境配置
1) Form 認證方式配置
<authentication mode="Forms"> <forms loginUrl="http://localhost/sfadmin/Account/Login" protection="All" timeout="240" name=".AuthCookie" /> </authentication>
2) Session 狀態存儲配置
<sessionState mode="InProc" customProvider="DefaultSessionProvider" timeout="480"> <providers> <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" /> </providers> </sessionState>
3) MachineKey 配置
<machineKey validationKey="zsdgfdg3FF1B0F88DDF585BA5D35E7BC87E3F0AB47FBBEBD12240DD3BEA2BEAEC4ABA215478658ugfjnhgfnmj3F22AD27E8FAD77DCFEE306219691434908D193A17C1FC8DCE51B71A4AE54920" decryptionKey="ECB6A3AF9ABBF3F16E80685ED68DC74B0B13CCEE538EBBA97D0B893139683B3B" validation="SHA256" decryption="AES" />
4) 登錄頁面重定向地址
<add key="FormAuthenticationRedirectUrl" value="http://localhost/sfadmin/Account/Login"/>
2.2 Session 對象操作和訪問
用於服務端用戶對象的身份信息存儲,包括用戶ID標識,用戶名稱,公司ID標識,票據信息和許可權數據等。
/// <summary> /// 獲取登錄用戶ID /// </summary> /// <param name="session"></param> /// <returns></returns> public int GetLogonUserID() { return (int)Get(WEB_LOGON_USER_ID); } public int GetLogonCompanyID() { return (int)Get(WEB_LOGON_COMPANY_ID); } /// <summary> /// 獲取登錄用戶Session的GUID /// </summary> /// <param name="session"></param> /// <returns></returns> public string GetLogonUserSessionGUID() { return Get(WEB_LOGON_SESSION_GUID).ToString(); } /// <summary> /// 獲取登錄用戶票據 /// </summary> /// <param name="session"></param> /// <returns></returns> public string GetLogonUserTicket() { var obj = Get(WEB_LOGON_USER_TICKET); var ticket = obj != null ? obj.ToString() : string.Empty; return ticket; }
2.3 Cookie 對象操作和訪問
前端JS腳本訪問用戶的特定信息,通過Cookie對象獲取來實現,大致代碼如下:
function getWebLogonUserCookie() { var name = "SlickOneWebLogonUserDataCookie"; var cookie = getCookie(name); if (cookie !== undefined) { var userAccount = $.parseJSON(cookie); return userAccount; } else { return null; } } lsm.getWebLogonUserID = function () { var userAccount = getWebLogonUserCookie(); var userID = userAccount.UserID; return userID; } lsm.getWebLogonCompanyID = function () { var userAccount = getWebLogonUserCookie(); if (userAccount !== null) { var companyID = userAccount.CompanyID; return companyID; } else { return ""; } }
2.4 登錄驗證後的票據存儲
用戶登錄之後,需要將其基本身份信息和關聯的角色或許可權數據存儲下來。而且作為前後端分離的系統,服務端需要使用這些票據數據,前端也需要通過Cookie對象訪問用戶信息,作為許可權控制的審核來源。
//create form ticket FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, loginName, DateTime.Now, DateTime.Now.AddMinutes(240), true, userDataContent, FormsAuthentication.FormsCookiePath); string ticString = FormsAuthentication.Encrypt(ticket); //write cookies in response //SetAuthCookie mark identity status true HttpContext.Current.Response.Cookies.Add(new HttpCookie("SlickOneWebCookie", ticString));
3. Mvc頁面及WebAPI安全訪問
3.1 Mvc頁面授權訪問
頁面控制器統一繼承於頁面基類,基類中重載方法OnActionExecuting(),讀取用戶身份信息,並存儲到Session對象,如果是非授權用戶,則跳轉到登錄頁面。代碼示例如下:
/// <summary> /// Authentication Verify When Action Executing /// </summary> /// <param name="filterContext"></param> protected override void OnActionExecuting(ActionExecutingContext filterContext) { var attr = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), true); bool isAnonymous = attr.Any(a => a is AllowAnonymousAttribute); if (isAnonymous == false) { var session = filterContext.HttpContext.Session; this.SessionManager.SetSession(session); var user = this.SessionManager.GetLogonUser() as WebLogonUser; if (user == null) { var webCookie = base.Request.Cookies["SlickOneWebCookie"]; if (webCookie != null && !string.IsNullOrEmpty(webCookie.Value)) { var encryptTicket = webCookie.Value; SaveUserSession(encryptTicket); } else { //Not a Valid Logon User, Need To Be Login Agagin var formRedirectUrl = WebConfigurationManager.AppSettings["FormAuthenticationRedirectUrl"].ToString(); string url = string.Format("{0}?ReturnUrl={1}", formRedirectUrl, Request.RawUrl); filterContext.HttpContext.Response.Redirect(url, true); } } } base.OnActionExecuting(filterContext); }
3.2 WebAPI 介面安全訪問
WebAPI控制器增加屬性過濾器,用於驗證是否是授權訪問的介面,其中需要從Cookie中讀取票據信息,驗證審核用戶是否是合法授權用戶。
/// <summary> /// check authorizaton information when action executing /// </summary> /// <param name="actionContext"></param> public override void OnActionExecuting(HttpActionContext actionContext) { //get authentication cookie from request var authCookie = actionContext.Request.GetCookie("SlickOneWebCookie"); if (!String.IsNullOrEmpty(authCookie)) { //decrypted user ticket information if (ValidateUserTicket(authCookie)) base.OnActionExecuting(actionContext); else actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized); } else { //verify webapi security setting bool isRquired = (WebConfigurationManager.AppSettings["WebApiSecurityEnabled"].ToString() == "true"); if (isRquired) { //check anonymous attribute var attr = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>(); bool isAnonymous = attr.Any(a => a is AllowAnonymousAttribute); if (isAnonymous) base.OnActionExecuting(actionContext); else actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized); } else { base.OnActionExecuting(actionContext); } } }
4. 主界面操作說明
主界面是整個後臺數據維護的入口頁面,集成了用戶基礎數據、流程數據、表單數據和其它設置頁面。其中流程定義,表單定義都鏈接到不同的WEB應用程式地址,這些WEB應用程式統一實現SSO要求的FORM認證,統一登錄地址等特性。保證一次登錄,再次免驗證就能訪問各子系統的簡捷操作。
5. 總結
SlickOne敏捷框架的示例項目,主要包括了基礎數據的維護,業務系統集成訪問,SSO單點登錄實現,MVC頁面安全和WebAPI安全訪問等功能特性。作為企業級應用系統的開發,可以完全擔當軟體團隊的技術統一框架解決方案。在後期的版本中,依然考慮企業用戶的需求,增加和構建功能模塊,做到框架軟體的可擴展和二次開發。
6. 參考