2009-07-13 100 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 
    } 
}