2009-07-13 96 views
2

我正在建立一个自定义的会员提供商,让我有我需要的安全方案摔跤。如何更改MembershipProvider的安全范例?

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

我已经拥有像这样一个签名的授权人对象:

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

将采取,例如,Person类型,查看接入(ENUM),并且用户检查它反对。现在,我已经将Authorize中的代码弄清楚了。

我的问题是,我如何从IPrincipal的IsInRole获得我的授权?我尝试过不同的事情,但他们都没有效果。我真的不喜欢魔术串的方法,但似乎我坚持下去。如果有办法以强类型的方式构建它,我肯定会更喜欢这种方式。有没有更好的方式来做到这一点,我没有想到?

回答

1

Anot她的方式我已经看到了这样的事情是在初始化用户存储所有权利和对象作为一个角色在校长。根据您拥有的对象数量,这可能是另一种选择。基本上你会摆脱授权人。授权调用,存储

  • 视图|人
  • 编辑|人
  • 附加|庇隆

三个不同的角色。我已经看到这种方法用于具有一系列特征的系统,因此您可能具有特征A→特征B,C或D,例如,如果您有A,则BC和D只能存在。这可以是角色,例如:

  • 一个
  • 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  
} 

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

+0

感谢您的建议Josh,我喜欢让PermissionFactory隔离魔法字符串生成的想法。但是,令牌生成在站点地图中并不会有用。在这种情况下你会如何处理站点地图?保持他们的魔术弦? – Joseph 2009-07-14 15:51:19

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 
    } 
}