2

我正在努力构建一个自定义会员提供程序,让我拥有我需要的安全方案。

我有自己的 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 页面的人都必须拥有对Person业务对象的查看权限。

我已经有一个 Authorizer 对象,其签名如下:

public static bool Authorize(Type type, Access access, IUser user)

例如,这将采用 Person 类型、View 访问权限(枚举)以及要检查的用户。现在,我已经弄清楚了 Authorize 中的代码。

我的问题是,我如何从 IPrincipal 的 IsInRole 到我的 Authorize?我尝试了不同的东西,但它们似乎都不起作用。我真的不喜欢魔术字符串的方法,但似乎我坚持下去了。如果有办法以强类型的方式构建它,我肯定会更喜欢它。有没有更好的方法来做到这一点,我没有想到?

4

2 回答 2

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
    }   
}
于 2009-07-14T15:36:34.840 回答
1

我看到这种事情的另一种方式是在初始化用户以将所有权限和对象作为角色存储在 Principal 中时。根据您拥有的对象数量,这可能是另一种选择。基本上你会摆脱 Authorizer.Authorize 调用,并存储

  • 查看|人
  • 编辑|人
  • 添加|庇隆

作为三个不同的角色。我已经看到它在具有功能层次结构的系统中使用,因此您可能具有功能 A -> 功能 B、C 或 D,例如,其中 BC 和 D 只有在您有 A 时才能存在。这可能是诸如:

  • 一种
  • A|B 或 A|C 或 A|D

因此,现在您的代码可以检查它们是否为 A,或者如果您需要检查子功能,您可以检查 A|B。

建议

为了让你的 impl 在你的页面加载中更好如果你这样做了:

if (Context.User.IsInRole(
       PermissionFactory.CreateToken(AuthorizationType.Person,Access.View)))  
{        
  //I have view rights, do some stuff    
}

现在您已经完全隐藏了这是一个字符串的事实。

于 2009-07-14T15:44:05.917 回答