前言:在應用于集團版客戶或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 ticketFormsAuthenticationTicket 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 trueHttpContext.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 Agaginvar 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 requestvar authCookie = actionContext.Request.GetCookie("SlickOneWebCookie");if (!String.IsNullOrEmpty(authCookie)){//decrypted user ticket informationif (ValidateUserTicket(authCookie))base.OnActionExecuting(actionContext);elseactionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);}else{//verify webapi security settingbool isRquired = (WebConfigurationManager.AppSettings["WebApiSecurityEnabled"].ToString() == "true");if (isRquired){//check anonymous attributevar attr = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();bool isAnonymous = attr.Any(a => a is AllowAnonymousAttribute);if (isAnonymous)base.OnActionExecuting(actionContext);elseactionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);}else{base.OnActionExecuting(actionContext);}}}
?4. 主界面操作說明
?主界面是整個后臺數據維護的入口頁面,集成了用戶基礎數據、流程數據、表單數據和其它設置頁面。其中流程定義,表單定義都鏈接到不同的WEB應用程序地址,這些WEB應用程序統一實現SSO要求的FORM認證,統一登錄地址等特性。保證一次登錄,再次免驗證就能訪問各子系統的簡捷操作。
?
5. 總結
SlickOne敏捷框架的示例項目,主要包括了基礎數據的維護,業務系統集成訪問,SSO單點登錄實現,MVC頁面安全和WebAPI安全訪問等功能特性。作為企業級應用系統的開發,可以完全擔當軟件團隊的技術統一框架解決方案。在后期的版本中,依然考慮企業用戶的需求,增加和構建功能模塊,做到框架軟件的可擴展和二次開發。
6. DEMO
- 演示地址:http://gc.slickflow.com/sfadmin/
- 用戶名和密碼:admin/123456
- 流程設計器:http://gc.slickflow.com/sfd/
- 表單設計器:http://gc.slickflow.com/smd/
7. 社區版源代碼
? ? SlickOne項目開源地址:
? ??http://github.com/besley/slickone?
8. 企業版授權說明
1) Demo僅作為功能演示使用,如需獲取產品完整源代碼和開發文檔,請申請企業版商業授權。
2) QQ群:151650479
3) EMail:?sales@ruochisoft.com
9. 參考
1.?SlickOne 敏捷開發框架介紹(一)