.NET 開源敏捷開發框架: SlickOne 敏捷開發框架介紹(二) -- 多用戶/多租戶/SAAS軟件基礎框架實現


前言:在應用於集團版客戶或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. DEMO

  1. 演示地址:http://gc.slickflow.com/sfadmin/
  2. 用戶名和密碼:admin/123456
  3. 流程設計器:http://gc.slickflow.com/sfd/
  4. 表單設計器: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 敏捷開發框架介紹(一)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM