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(, loginName, DateTime.Now, DateTime.Now.AddMinutes(),
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
- 演示地址: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. 参考
SlickOne 敏捷开发框架介绍(二) -- 多用户/多租户/SAAS软件基础框架实现的更多相关文章
- SlickOne敏捷开发框架介绍(一) -- 基于Dapper, Mvc和WebAPI 的快速开发框架
前言:在两年前(最初发布时间:2013年1月9日(csdn),当前文章时间2015年11月10日),项目组推出了基于Dapper,Mvc和WebApi的快速开发框架,随着后续Slickflow产品的实 ...
- 基于DDD的.NET开发框架ABP实例,多租户 (Saas)应用程序,采用.NET MVC, Angularjs, EntityFramework-介绍
介绍 基于ABPZERO的多租户 (Saas)应用程序,采用ASP.NET MVC, Angularjs-介绍 ASP.NET Boilerplate作为应用程序框架. ASP.NET MVC和ASP ...
- java 快速开发框架平台 二次开发 代码生成器 springmvc SSM后台框架源码
官网 http://www.fhadmin.org/D 集成安全权限框架shiro Shiro 是一个用 Java 语言实现的框架,通过一个简单易用的 API 提供身份验证和授权,更安全,更可靠E ...
- RDIFramework.NET敏捷开发框架 ━ 工作流程组件介绍
RDIFramework.NET,基于.NET的快速信息化系统敏捷开发.整合框架,给用户和开发者最佳的.Net框架部署方案. 1.RDIFramework.NET敏捷开发框架介绍 RDIFramewo ...
- RDIFramework.NET ━ .NET敏捷开发框架全新发布-最好用的.NET开发框架 100%源码授权
RDIFramework.NET,基于.NET的快速信息化系统敏捷开发框架.10年沉淀.历经上千项目检验,致力于企业智能化开发,帮助提升软件开发效率.最好用的.NET开发框架,100%源码授权. 1. ...
- 如何提高码农产量,基于ASP.NET MVC的敏捷开发框架之移动端开发随笔二
前言 在前一篇文章中我已经做过开篇,接下来的随笔会详细讲一下我们的开发框架是如何实现的,专业的事由专业的人来讲,以后就由我们的高级码农小李英文名查尔斯和他的师父厂长(因为姓陈,酷爱摄影,我们的文艺片都 ...
- RDIFramework.NET敏捷开发框架通过SignalR技术整合即时通讯(IM)
1.引言 即时通讯(IM)是RDIFramework.NET敏捷开发框架全新提供的一个基于Web的即时通讯.内部聊天沟通的工具.界面美观大方对于框架内部进行消息的沟通非常方便.基于RDIFramewo ...
- RDIFramework.NET敏捷开发框架 ━ 工作流程组件Web业务平台
接前两篇: RDIFramework.NET敏捷开发框架 ━ 工作流程组件介绍 RDIFramework.NET敏捷开发框架 ━ 工作流程组件WinForm业务平台 1.RDIFramework.NE ...
- RDIFramework.NET敏捷开发框架Web新增邮件中心实现便捷式的邮件收发
1.引言 邮件收发在很多业务系统中都有这样的需求,是比较正式和常用的功能.在我们的框架中提供了邮件中心功能模块,集内部邮件的收发.邮件归类.邮件星标的标记.邮件的删除与彻底删除等,邮件中心功能模块界面 ...
随机推荐
- Excel VBA保护工作表
'设定可编辑区域 ActiveSheet.Protection.AllowEditRanges.Add Title:="区域1", Range:=Range("E5:H1 ...
- unp学习笔记——Chapter1
1.发现网络拓扑的几个重要的命令 (1).netstat -i 提供网络接口的信息.我们还指定-n 标志以输出数值地址,而不是试图把它们反向解析成名字.netstat -r 展示路由表. dzhwen ...
- Export SQLite data to Excel in iOS programmatically(OC)
//For the app I have that did this, the SQLite data was fairly large. Therefore, I used a background ...
- cordova app 监听物理返回键
物理返回键指的是手机系统自带的返回按钮,通过cordova监听返回按钮操作,可以禁止某些页面的返回操作,以及实现点击两次返回按钮退出应用. var pageUrl = window.location. ...
- Eric6启动时“无法定位序数4540于动态链接库LIBEAY32.dll”的错误
参考自:https://blog.csdn.net/HongAndYi/article/details/80721478 在安装PyQt5的编程环境时,安装Eric6-17.12后运行eric6,却出 ...
- python3转变exe的方法
python开发的代码可能在其他windows上并不能使用用,除非别人的环境中也有python. 下面是如何将python开发的东西转为exe格式 1.安装pyinstaller pip instal ...
- 数组slice方法
slice slice(start,end):方法可从已有数组中返回选定的元素,返回一个新数组,包含从start到end(不包含该元素)的数组元素.(不会改变原数组) start参数:必须,规定从何处 ...
- go make切片中len() 和 cap() 的差别
对于make slice而言,有两个概念需要搞清楚:长度跟容量. 容量表示底层数组的大小,长度是你可以使用的大小. 容量的用处在哪?在与当你用 appen d扩展长度时,如果新的长度小于容量,不会更换 ...
- 通过微信Android和iOS版,看两大系统的差异
由于设计师或者产品经理使用的移动设备大部分是iPhone,所以在做设计时,容易忽略Android和iOS的差异,按照自己的使用习惯进行设计,导致大部分设计师或产品经理做出的设计都是基于iOS规范或习惯 ...
- WinForm1
一.窗体的各种属性 二.控件 1.公共控件 2.容器控件 3.菜单控件