编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> 架构设计 -> SlickOne 敏捷开发框架介绍(二) -> 正文阅读

[架构设计]SlickOne 敏捷开发框架介绍(二)

前言:在应用于集团版客户或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. 参考
1. SlickOne 敏捷开发框架介绍(一)
  架构设计 最新文章
spring boot实现ssm(2)功能
java 企业站源码 兼容手机平板PC 自适应响应
Serverless无服务应用架构纵横谈
理论篇:关注点分离(Separation of concern
Struts 2 入门
spring boot实现ssm(1)功能
SpringMVC通过Redis实现缓存主页
网络应用的编程模型
应用服务器和Web服务器
java 企业网站源码 后台 springmvc SSM 前台
上一篇文章      下一篇文章      查看所有文章
加:2017-12-05 23:24:51  更:2017-12-05 23:24:53 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 三丰软件 开发 中国文化 阅读网 日历 万年历 2019年9日历
2019-9-16 19:14:52
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识