CSLA的权限控制如何整合到框架中
Posted 炼金士
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSLA的权限控制如何整合到框架中相关的知识,希望对你有一定的参考价值。
CSLA对类的属性读写控制做的很到位。
首先在BusinessBase继承的类中继承AddAuthorizationRules函数:
protected override void AddAuthorizationRules()
{
...
AuthorizationRules.AllowWrite(PasswordProperty, UserPrincipal.AdminRoleName);
}
然后将属性注册一下(这个注册机制还有其他用处;CSLA采用注册而非反射机制,看来主要还是考虑整体系统性能,不过辅以类似缓存的技术,性能也不会差到哪里,Phenix.Core.DataMapper就是这么做的):
private static PropertyInfo<string> PasswordProperty =
RegisterProperty<string>(typeof(User), new PropertyInfo<string>("Password"));
[Phenix.Core.DataMapperField(NeedUpdate = true, ColumnName = "US_Password")]
private string _password = PasswordProperty.DefaultValue;
/// <summary>
/// 登录口令
/// </summary>
public string Password
{
get
{
return GetProperty<string>(PasswordProperty, _password);
}
set
{
SetProperty<string>(PasswordProperty, ref _password, value);
}
}
至此,在UI界面上,仅需加上组件:ReadWriteAuthorization,那么相关的数据感知控件,比如输入框等,即可按照在AddAuthorizationRules函数中定义的读写权限进行只读和使能控制:
实现IExtenderProvider接口:
public bool CanExtend(object extendee)
{
if (IsPropertyImplemented(extendee, "ReadOnly")
|| IsPropertyImplemented(extendee, "Enabled"))
return true;
else
return false;
}
但是,CSLA对类的权限控制不是很到位,需要框架对此进行二次开发。
类的权限控制分为两个层次:
1,浏览权限;
2,增删改权限;
浏览权限是优先判断的,其次才对增删改进行判断。
根据目前CSLA提供的功能,在BusinessListBase中实现:
#region 权限控制
/// <summary>
/// 是否可以浏览数据
/// </summary>
[Browsable(false)]
public static bool AllowBrowse
{
get
{
return Csla.Security.AuthorizationRules.CanGetObject(typeof(T));
}
}
/// <summary>
/// 是否可以新增数据
/// </summary>
[Browsable(false)]
public new bool AllowNew
{
get
{
return Csla.Security.AuthorizationRules.CanCreateObject(this.GetType());
}
}
/// <summary>
/// 是否可以删除数据
/// </summary>
[Browsable(false)]
public new bool AllowRemove
{
get
{
if (Count == 0)
return false;
return Csla.Security.AuthorizationRules.CanDeleteObject(this.GetType());
}
}
/// <summary>
/// 是否可以编辑数据
/// </summary>
[Browsable(false)]
public new bool AllowEdit
{
get
{
if (Count == 0)
return false;
return Csla.Security.AuthorizationRules.CanEditObject(this.GetType());
}
}
#endregion
至此,只要在继承BusinessListBase的类中,实现AddObjectAuthorizationRules静态函数,比如:
protected static void AddObjectAuthorizationRules()
{
Csla.Security.AuthorizationRules.AllowGet(typeof(Users), UserPrincipal.AdminRoleName);
Csla.Security.AuthorizationRules.AllowCreate(typeof(Users), UserPrincipal.AdminRoleName);
Csla.Security.AuthorizationRules.AllowEdit(typeof(Users), UserPrincipal.AdminRoleName);
Csla.Security.AuthorizationRules.DenyDelete(typeof(Users), UserPrincipal.AdminRoleName);
}
就可以实现类的权限数据的获取,不过函数名不能写错,否则CSLA就找不到了:
internal class ObjectAuthorizationRules
{
...
internal static RolesForType GetRoles(Type objectType)
{
RolesForType result = null;
if (!_managers.TryGetValue(objectType, out result))
{
lock (_managers)
{
if (!_managers.TryGetValue(objectType, out result))
{
result = new RolesForType();
_managers.Add(objectType, result);
// invoke method to add auth roles
var flags =
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
MethodInfo method = objectType.GetMethod(
"AddObjectAuthorizationRules", flags);
if (method != null)
method.Invoke(null, null);
}
}
}
return result;
}
...
}
但是,类的权限数据的处理和应用,现在只能靠开发者在业务系统中硬编码:
/// <summary>
/// 管理用户窗体
/// </summary>
public partial class UsersEditForm : Form
{
...
/// <summary>
/// 应用授权规则
/// </summary>
private void ApplyAuthorizationRules()
{
bindingNavigatorAddNewButton.Enabled = Users.AllowNew;
bindingNavigatorDeleteButton.Enabled = Users.AllowRemove;
usersBindingNavigatorCancelButton.Enabled = Users.IsDirty;
usersBindingNavigatorSaveButton.Enabled = Users.IsSavable;
readWriteAuthorization.ResetControlAuthorization();
}
...
}
至于如何在框架中封装掉,目前还在思考当中。。。
以上是关于CSLA的权限控制如何整合到框架中的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot2.0 整合 SpringSecurity 框架,实现用户权限安全管理
SpringBoot整合SpringSecurity权限控制(动态拦截url+单点登录)