我正在努力建立一个自定义会员提供商,让我拥有我需要的安全方案。
我拥有自己的IPrincipal,IIdentity和MembershipProvider。我认证工作正常。我现在遇到的问题是授权。
我对授权方案的问题是继承在IPrincipal的IsInRole行为中。这种行为与ASP.NET Webforms的各种功能紧密相关,我主要关注的是站点地图授权,因为如果可以,我想使用它。
所以你传统上可能有这样的站点地图:
<siteMap xmlns="blahblah">
<siteMapNode url="PersonView.aspx"
title="View Person"
description="View the details of a person"
roles="ViewerRole" />
</siteMap>
在这里,任何试图访问PersonView.aspx页面的人都需要拥有ViewerRole。这是我的问题出现的地方。我不希望将我的授权与用户的角色联系起来。相反,我希望授权与我正在执行的行为联系起来,并让幕后的一些基础事物处理授权。
所以我真正想要的是这样的事情:
<siteMap xmlns="blahblah">
<siteMapNode url="PersonView.aspx"
title="View Person"
description="View the details of a person"
roles="Person|View" />
</siteMap>
这应该被解释为任何试图访问PersonView.aspx页面的人都必须拥有人业务对象的查看权限。
我已经拥有一个具有如下签名的Authorizer对象:
public static bool Authorize(Type type, Access access, IUser user)
例如,Person类型,View访问(枚举)以及要对其进行检查的用户。现在,我在Authorize中找到了代码。
我的问题是,如何从IPrincipal的IsInRole获取我的授权?我尝试了不同的东西,但似乎都没有。我真的不喜欢神奇的弦乐方法,但似乎我坚持了它。如果有一种方法以强类型的方式构建它,我肯定会更喜欢它。有没有更好的方法来做到这一点,我没想到?
答案 0 :(得分:1)
我想出了一个非常干净的方法来解决我的问题。我所做的是更改我的授权签名以接受枚举而不是类型,并在IsInRole中使用它来确定权限。
所以我有:
public static bool Authorize(AuthorizationType type, Access access, IUser user)
然后我在IsInRole中使用它,如下所示:
public bool IsInRole(string role)
{
var typeAndAccess = role.Split('|');
var authType =
(AuthorizationType)Enum.Parse(
typeof(AuthorizationType), typeAndAccess[0]);
var access = (Access)Enum.Parse(typeof(Access), typeAndAccess[1]);
return Authorizer.Authorize(
authType, access, Context.User.Identity as IUser);
}
这允许我在必要时使用魔术字符串方法(如在站点地图中),但是当我以编程方式使用它时,它还允许我使用更强类型的方法:
void Page_Load(...)
{
if (Context.User.IsInRole(AuthorizationType.Person + '|' + Access.View)
{
//I have view rights, do some stuff
}
}
答案 1 :(得分:1)
我看到这种事情的另一种方式是将用户初始化为将所有权利和对象存储为Principal中的角色。根据您拥有的对象数量,这可能是另一种选择。基本上你将摆脱Authorizer.Authorize调用,并存储
作为三个不同的角色。我已经看到这在一个具有特征的系统中使用,所以你可能有特征A - &gt;特征B,C或D,例如,如果你有A,那么B C和D只能存在。这可能是以下角色:
现在您的代码可以检查他们是否是A或者如果您需要检查子功能,您可以检查A | B.
<强>建议强>
为了让你的页面加载更好,如果你这样做了:
if (Context.User.IsInRole(
PermissionFactory.CreateToken(AuthorizationType.Person,Access.View)))
{
//I have view rights, do some stuff
}
现在你已经完全隐藏了这是一个字符串的事实。