信息系统开发平台OpenExpressApp-功能权限日来源:博客园作者:快乐学习收藏本文在《信息系统开发平台OpenExpressApp-用户权限模块设计》中对RBAC以及在OEA中的涉及进行了简要介绍,上篇《信息系统开发平台OpenExpressApp-用户管理》介绍了基本的用户管理,本篇继续讲解基于用户的功能权限管理,下一篇介绍数据权限。部门管理部门相当于组织机构,目前只是简单的实现了最基本的一种模式。部门下面挂接岗位,这是部门+岗位=角色,角色下挂接人和功能权限,后面将增加数据权限。以下为权限相关的类图:其中,OrgPisitionOperation为角色的功能权限对象,功能对象Operation引用了CommandBase,所以OEA的功能权限中显示可管理的功能是所有的Command,包括toolbar上的以及右键菜单上的命令,具体实现就不说了,大家以后可以去看具体代码。功能权限PBS模板界面如下图所示:在【功能权限】显示如下,左边会列出系统所有模块,右边列出的是每个模块下的所有可控制的对象,在根对象会多出一个【打开模块】内置权限,后一小节会讲一下:这些功能都是我们编写的Command以及OEA内置的Command,也就是在界面能够看到的按钮、菜单等都可以控制。目前还不提供快捷方式设置,如设置可更改,则自动把添加、添加子等一并修改。当设置后,再次登录时,不允许操作的功能,AutoUI不会自动生成这些命令。privatestaticvoidCreateCommandsForToolBar(ToolBartoolbar,TypeboType,ObjectViewview,BoInfoOperationListcommands){......for(inti=0,c=commands.Count;ic;i++){varcommand=commands[i].Operation.Command;//考虑权限if(!(Csla.ApplicationContext.User.IdentityasOEAIdentity).HavePermissionOnOperation(boInfo.Id,newGuid(command.Id)))continue;打开模块权限登录系统时,系统需要根据当前用户来生成模块列表。第一张图为所有功能列表,在第二张图表示的【部门管理】的【功能权限】中对业务对象去除了【打开模块】功能时,再次登录后看到图三模块列表。//获取模块列表数据源IListBusinessObjectInfomodules=newListBusinessObjectInfo();if(Csla.ApplicationContext.User.Identity.IsAuthenticated){foreach(variteminApplicationModel.Modules){if((Csla.ApplicationContext.User.IdentityasOEAIdentity).HavePermissionOnOperation(item.Id,newGuid(CommandNames.OpenModule)))modules.Add(item);}}信息系统开发平台OpenExpressApp-使用CSLA类库实现用户管理日来源:博客园作者:快乐学习收藏本文在《信息系统开发平台OpenExpressApp-用户权限模块设计》中对RBAC以及在OEA中的涉及进行了简要介绍,权限的基础必须存在用户,实现自定义用户管理,CSLA已经提供一些类库来继承使用,本篇简单的讲解一下如何使用CSLA类库实现用户管理以及登录,下一篇再介绍功能权限部分。用户管理模块这个其实就是一个用户字典管理,包括用户名、登录名和密码,没有考虑证书等功能,由于目前实现比较简单,User类库编写按照以往类库就行了,这里就不单独讲了。实现用户主体Principal主体实现登录和退出功能,登录成功后返回用户,否则为非法用户。CSLA实现了一个类BusinessPrincipalBase,我们只要从它继承下来就可以很方便的实现OEA的Principal对象,这个对象在登录窗口时调用调用。Principal代码如下:publicclassOEAPrincipal:BusinessPrincipalBase{privateOEAPrincipal(IIdentityidentity):base(identity){}publicstaticboolLogin(stringusername,stringpassword){varidentity=OEAIdentity.GetIdentity(username,password);if(identity.IsAuthenticated){OEAPrincipalprincipal=newOEAPrincipal(identity);Csla.ApplicationContext.User=principal;returntrue;}else{Csla.ApplicationContext.User=newUnauthenticatedPrincipal();returnfalse;}}publicstaticvoidLogout(){Csla.ApplicationContext.User=newUnauthenticatedPrincipal();实现用户标识Identity通过用户名和密码去服务器端查询后返回用户标识对象,在这里会把角色也返回过来,角色部分功能权限blog中再介绍。///summary///注意:防止重名,User增加Code区分唯一性,查询时通过Code查询,同时返回Code和Name////summary[Serializable()]publicclassOEAIdentity:CslaIdentity{#regionFactoryMethodsinternalstaticOEAIdentityGetIdentity(stringusername,stringpassword){returnDataPortal.FetchOEAIdentity(newUsernameCriteria(username,password));}publicUserUser{get;set;}privateOEAIdentity(){/*requireuseoffactorymethods*/}#endregion#regionDataAccesspublicnewOrgPositionsRoles{get;privateset;}privatevoidDataPortal_Fetch(UsernameCriteriacriteria){User=UserList.Get(criteria.Username,criteria.Password);if(null!=User){base.Name=User.Name;base.IsAuthenticated=true;this.Roles=OrgPositions.GetList(User.Id);//listofrolesfromsecuritystore}else{base.Name=string.Empty;base.IsAuthenticated=false;this.Roles=null;}}#endregion}信息系统开发平台OpenExpressApp-支持勾选视图日来源:博客园作者:快乐学习收藏本文在OpenExpressApp中部门+岗位=角色,功能权限属于角色的,所以功能权限也放在部门模块中设置了,后期将会单独对权限部门进行介绍,本篇讲解一下在功能权限实现中使用到的一种新的内置视图样式,我把它叫做勾选视图。之前的列表视图OEA的所有Command都有一个Guid,角色下功能权限下存储的实际上是不能使用的功能的Guid,如果按照以往来实现,界面如下:查看原图(大图)界面左边为模块,右边为分组的对象功能列表,这时可以通过设计一个【选择】功能,弹出一个对话框,对话框显示所有模块的所有对象功能列表,然后通过选择后加入细表。虽然这样可以很方便的使用以前框架的功能来实现,但是用户使用起来会很不方便。这种方式,勾选一个功能需要需要点击弹出对话框,然后选择一些内容,然后关闭。而系统模块功能可能很多,这样操作就会让用户点击按钮多次。新增的勾选视图查看原图(大图)勾选视图界面显示如上图所示,右边把原来弹出的对话框内容显示在这里,前面加了一个checkbox框提供选择,通过勾选操作来实现以往的选择功能。现在用户新增或者去除一个功能,只需要勾选一次就可以解决,而以往操作需要3个步骤。之前项目任务中就遇到过类似操作,当时就想实现一个通用视图来提高易用性,不过由于时间原因没有做,直到今天才完成。下面介绍一下勾选视图的主要实现和使用。为了下面讲解时对数据说明清楚,定义一下两个术语:源数据:勾选的列表,相当于以前弹出选择框的数据目的数据:操作的对象列表,通过勾选操作影响到的实际对象实现要求由于这只是操作样式不一样,所以我不希望在以前的业务对象类库里加入这部分功能,这部分功能与类库隔离开来把这个功能抽象为一中通用的样式视图,通过一些属性设置和约定来实现延用以前框架代码,在之前框架代码上扩展框架内部实现UI勾选列表是一个列表视图,所以可以重用以前的ListObjectView,只是需要增加一个checkbox列。现在实现为通过附加属性来实现publicstaticreadonlyDependencyPropertyIsCheckedProperty=DependencyProperty.RegisterAttached(IsChecked,typeof(bool),typeof(SelectedDataAttached),newFrameworkPropertyMetadata(newPropertyChangedCallback(OnIsCheckedChanged)));///summary///HandleschangestotheIsCheckedproperty.////summaryprivatestaticvoidOnIsCheckedChanged(DependencyObjectd,DependencyPropertyChangedEventArgse){if(disDataGrid){DataGridgrid=dasDataGrid;if((bool)e.NewValue){DataGridCheckBoxColumncolumn=newDataGridCheckBoxColumn(){Header=选择};column.Binding=newBinding(PropertyConvention.IsSelected);grid.Columns.Insert(0,column);}else{if((grid.Columns[0]isDataGridCheckBoxColumn)&&((string)grid.Columns[0].Header==选择))grid.Columns.RemoveAt(0);}}}数据以前UI显示的数据是父对象的子对象列表属性(目的数据),现在需要显示为源数据,则需要修改LoadData,///summary///装载数据,考虑(AssociationOperateType.Selected////summarypublicoverridevoidLoadData(){base.LoadData();if((AllowLoadData)&&(AssociationOperateType.Selec