2016-03-07 53 views
1

我正在讀入FormsAuthentication以遷移遺留應用程序。此應用程序使用用戶的角色/權限如下結構:FormsAuthentication和數據庫支持的嵌套角色

class Account 
{ 
    public ISet<Role> Roles 
    { 
     get; 
     set; 
    } 

    public static bool Has(Permission permission_) 
    { 
     foreach (Role role in Roles) { 
      if (role.Permissions.Contains(permission_)) { 
       return true; 
      } 
     } 

     return false; 
    } 

} 

class Role 
{ 
    public ISet<Permission> Permissions 
    { 
     get; 
     set; 
    } 
} 

public enum Permission 
{ 
    ACCESS_COMPONENT_XYZ 
    EDIT_FIELD_ABC 
    VIEW_ENTITY_123 
} 

Role s爲剛剛權限的集合,並在代碼本身,只有權限檢查,如

model.CanEditFieldAbc = account.Has(Permission.EDIT_FIELD_ABC); 

所有這一切都由使用NHibernate的數據庫支持。現在,據我瞭解FormsAuthentication,這對角色使用「一維」方法。這意味着,我只在AuthenticationToken中有一個字段來填寫我的權限。

我相信我需要以某種方式獲得帳戶實體的所有權限到當前已驗證的令牌。我的問題是:我該怎麼做?我知道如何進行身份驗證,但不知道如何將我的自定義權限集(例如字符串)存入該令牌中?

目前我登錄控制器看起來是這樣的:

// "Accounts" is a NHibernate repository on the base controller 
Account account = Accounts.Unique(form_.Name); 

if (account != null) { 
    byte[] salt = Convert.FromBase64String(account.Salt); 
    byte[] password = Convert.FromBase64String(account.Password); 

    if (PWDTK.ComparePasswordToHash(salt, form_.Password, password)) { 
     FormsAuthentication.SetAuthCookie(form_.Name, false); 
     // How to get the complete set of "account.Roles -> Permission" into the Cookie/Token? 
    } 
    else { 
     throw new AuthenticateException("Wrong credentials"); 
    } 
} 
else { 
    throw new AuthenticateException("Wrong credentials"); 
} 

當然,我可以從數據庫中爲每個請求獲取當前的帳戶,然後我有它內部的一組角色/權限(感謝nhibernate懶加載等),但這似乎是錯誤的,因爲FormsAuthenticate已經提供了類似的東西?

回答

1

角色應該由角色提供者處理。在你的情況下,你應該writeconfigure你自己的角色提供者。

登錄時,您的代碼不必關心提供角色,框架將使用您在配置中定義的角色提供者。您只需在成功登錄時撥打RedirectFromLoginPage(如果您不想使用內置重定向,則需要撥打SetAuthCookie)。

而對於檢查角色,則應該使用UserIsInRole方法。

+0

感謝提示,這已經在幫助很多。但有一個問題:如何讓我的NHibernate存儲庫進入該類?在這個例子中,它使用連接字符串進行手動連接,該連接字符串違背了我目前構建的所有功能(流利NHibernate配置等)。有沒有辦法將這些連接注入提供者? –

+0

它只是一個示例提供程序。你應該使用你選擇的數據訪問方法(邏輯上,NHibernate)編寫你自己的。不幸的是,你對角色提供者的生命週期幾乎沒有任何控制,所以爲了注入依賴關係,這很麻煩。你可以在'Initialize'方法中做一些依賴關係解析。 (通過示例使用'System.Web.Mvc.DependencyResolver.Current.GetService ()')。但是您的依賴框架可能尚未在該步驟初始化。 –