2013-03-05 67 views
1

我正在重寫ASP.NET中的PHP網站並編寫會員系統。MVC 4:傳遞用戶組數據

我明白我可以擴展到的MembershipUser成員添加特定的屬性,但我怎麼能繞過布爾組信息,如使用搜索編輯帖子等,這是不特定於用戶的?有沒有我缺少的框架項目,或者我應該創建一個超級對象來傳遞這個和其他設置?

本質上是我想要的一種有效的方式來訪問我的控制器中的用戶組屬性。

+0

請說明您訪問的方式。你需要使用Membership調用還是你願意使用db? – 2013-03-08 03:02:19

+0

當前我的成員信息和組信息在數據庫中,並且作爲第一階段,我不更改DB(MySQL),而只更改PHP >> ASP.NET代碼。將我的解決方案融入MVC成員框架似乎越來越不利,除非我錯過了某些與安全有關的東西?我沒有看到任何安全優勢,但只有我需要擴展然後重新進行的約束(例如MembershipUser)。尋找一個可靠的解決方案,或至少指出正確的方向。 – InContext 2013-03-08 10:37:15

+0

我總是用外鍵userID(GUID)創建一個用戶表。我創建了一個視圖(usersView)加入我的用戶表和aspnet_users表。最後,我將usersView加載到我的EDMX文件中。 – 2013-03-08 13:35:52

回答

1

除了擴展MembershipProvider之外,您還可以擴展RoleProvider。 RoleProvider負責檢查用戶屬於哪個組,註冊新角色,向角色添加用戶等。要使用角色,您將使用包含許多靜態方法的Roles類。

除此之外,每當您點擊一個控制器時,您可以查詢HttpContext.User屬性實現IPrincipal。此屬性具有方法IsInRole,用於與RoleProvider通信以獲取用戶是否在特定組中的信息。

另外,爲了允許訪問控制器或操作,您可以使用Authorization屬性並列出可以訪問控制器的特定角色。

的角色可以存儲在cookie(對它們進行緩存),也可以在Global.asax的實施Application_AuthenticateRequest和手動初始化GenericPrincipal。這個對象被傳遞給HttpContext.User。此對象的構造函數接受使用IsInRole方法查詢的角色數組。

protected void Application_AuthenticateRequest(Object sender, EventArgs e) 
{ 
    // Check if user is authenticated 
    if (HttpContext.User != null) 
    { 
     // Extract roles from a cookie if you used FormsAuthentication 
     // or read them from a cookie or from some other cached location 

     // Split roles into array of strings 
     var roles = listOfRoles.ToArray(); // If it is stored in a List<string>. 
     var identity = HttpContext.User.Identity; 
     var principal = new GenericPrincipal(identity, roles); 

     HttpContext.User = principal; 
    } 
} 

上述代碼未經測試。我從頭腦寫下它。它應該給你一個很好的圖像,如何緩存角色並以最有效的方式使用它們。

UPDATE如果您需要更高級的選項,其中每個角色可以具有一個或多個功能,如「使用搜索」,「可以做某事」,「可以做到」,我會實現以下安全性邏輯:

  • 用戶
  • 角色(用戶屬於角色)
  • AccessRight(角色可以具有權的一個或多個訪問)。

UsersRoles表將用於將用戶添加到特定角色。 RolesAccessRights表是您爲每個角色定義特定權限的位置。 用戶永遠不會與功能對話。 (順便說一句,這個命名約定只是一個例子,你將遵循你的命名約定)。

在我上一個工作中,我們是如何實現審計系統的(這是基於Web窗體的)。但是,在MVC中,您可以覆蓋AuthorizationAttribute以檢查用戶的角色並檢查角色是否定義了訪問權限。考慮到你有特定的安全需求,你必須在你看到需求和必要性的每一個行動中使用這個屬性。

如果您計劃實施此邏輯,請忘記Membership,MembershipUser和Roles。老實說,我不再使用這些類。我有我自己的自定義安全性,我實現了我在最後4個項目中使用的安全性,而不需要更新或修改。

UPDATE 2:我們使用的安全解決方案基於自定義MembershipProvider和RoleProvider。現在想一想,依靠它是一個錯誤,因爲訪問AccessLevel表必須通過Entity Framework進行映射。因此我們不得不去查詢我們的安全表。

我給你的建議是完全忽略與會員和角色相關的類。第一個原因是,當你覆蓋提供者時,你會避免使用不必要的方法和屬性。在方法體中使用throw new NotSupportedException()的方法太多了。

建議實施

您需要下表:

  1. 用戶 - (至少需要三列用戶ID,用戶名,密碼)。如果你想散列密碼,你也可能需要儲存鹽。其他列如FirstName,LastName等。我建議你存儲在不同的表中並用UserId將其鏈接起來。至於UserId類型,是否使用intGuid取決於您。
  2. 角色 - (您需要至少兩列RoleId,RoleName)。同樣,與UserId一樣,您需要使用哪種數據類型。
  3. UsersRoles - Store UserId和RoleId。您可能想要存儲屬性,例如角色IsActive這是一個比特值。
  4. AccessRights - 這是您存儲訪問權的關鍵所在。在你的情況下,就像UseSearch,EditPosts,DeletePosts等在這裏你應該至少使用三列AccessRightId,AccessRightKey和AccessRightDescription。如果您有很多訪問權限密鑰,此說明字段將變得非常有價值。
  5. RolesAccessRights - 這是您定義添加特定訪問權限的角色。還有IsActive位值爲了禁用角色的特定訪問權限。

在MVC中,您將覆蓋AuthorizationAttribute。在此屬性中,您將指定可訪問控制器和/或操作的訪問權限列表。你打算如何做到這一點完全取決於你,但我會創建一個枚舉值與AccessRightsKeys相同的值列表。這樣你可以使用強類型的訪問權限而不是基於字符串的列表。有關實現自定義授權屬性的更多信息,請參閱參考列表。

在此屬性內部,您將讀取用戶標識並檢索角色。比較您爲角色指定的AccessRightsKeys(RolesAccessRights表)以查看角色是否具有訪問權限以及該規則是否處於活動狀態。

至於基於解決方案的實現,我將實現與基於安全的存儲庫和工作單元解決方案進行通信的安全服務層。因爲你正在使用MySQL,所以我不知道你可以使用哪個ORM,或者你必須依賴ADO.NET和OLEDB提供程序來使用MySQL。

我通常的做法是自上而下的方法。我從高層實現(比如表示層)並向下走向數據訪問層。這樣最後我只有那些我真正使用的方法,沒有冗餘。

那麼,我希望這給你一些關於如何這個圖片。至於時間,你可以在大約8-10個小時內完成。

參考:

  1. Implementing a Role Provider
  2. Roles Class
  3. How to: Create a Custom AuthorizationAttribute
+0

我有上面的但角色只是一個字符串而沒有更復雜,所以我只能在那裏存儲一個名字。但是如果每個角色都需要更多的屬性,比如「可以使用搜索」,那麼它將如何存儲?它太泛泛無法擴展MembershipUser和角色,不允許任何比字符串更復雜的東西。我是否需要傳遞某種設置對象,然後在此查找權限,或者有沒有一種方式我不知道使用角色? – InContext 2013-03-07 20:46:04

+0

我接下來的結論是,框架確實不會帶來任何好處。你上面的* AccessRight *不是框架的一部分,而是一些自定義的東西?如果是這樣的話,那麼使用該框架除了具有與用戶有關的集合結構和方法調用之外還有什麼好處? – InContext 2013-03-08 10:39:59

+0

AccessRight是一個自定義表格。 .NET提供的標準安全操作相當不錯,但有時你必須創建一些完全自定義的東西。上述解決方案實施起來並不困難或複雜。如果你想要,我可以詳細說明我的答案,描述我們如何使用它。如果可以詳細說明,請致電 – 2013-03-08 12:14:50