2013-10-07 54 views
0

我在編程方面頗爲新穎,我的英語很糟糕,所以我很抱歉如果這篇文章讓你感到困惑。基於MVC項目的角色

我正在實施一個基本的ASP .NET MVC Web應用程序,它將管理公司的信息。 在這個應用程序中有兩個頁面。 一個用於查看信息,無需任何訪問此頁面的信息。 另一個用於編輯您可以訪問此頁面的信息,只要您擁有公司的管理員角色。

public ActionResult ViewInfo(string companyId) 
    { 
     return View(); 
    } 

    [Authorize(Roles = "Admin")] 
    public ActionResult EditInfo(string companyId) 
    { 
     return View(); 
    } 

如果我有可以訪問到2家公司的帳戶,但該帳戶在這兩個公司的完全不同的角色。 (例如,帳戶是公司A的管理員和公司B的普通用戶)。

是否有任何簡單的方法可以根據我將要訪問的公司獲取角色?我試過使用自定義RoleProvider,但似乎我無法將其他參數傳遞給該方法。

有點像這樣?

public class CustomRoleProvider : RoleProvider 
{ 
    public override bool IsUserInRole(string username, string roleName) 
    { 
      string companyId = GetCompanyId(); // Is there any good way to get this companyId from the Controller? 
      return userCompanyRoles.Any(u => u.Username == username && u.CompanyId == companyId && u.Roles.Any(r => r.Name == roleName)); 
    } 

    ... 

} 

編輯

車型有4款在我的應用程序:

public class User { 
     public string Id { get; set;} 
     ... 
    } 

    public class Company { 
     public string Id { get; set;} 
     ... 
    } 

    public class Role { 
     public string Name { get; set;} 
     ... 
    } 

    public class UserCompanyRoles { 
     public string UserId { get; set; } 
     public string CompanyId { get; set; } 
     public List<string> Roles { get; set; } 
    } 

所以表看起來像這樣

UserId CompanyId Role 
    1  A   User 
    1  A   Admin 
    1  B   User 
    2  B   Admin 
    2  C   User 
    3  A   Admin 
    3  C   Admin 
+0

你還會預計公頃超過2家公司? –

+0

@ErikPhilips當然!而且不同的角色也會有更多的頁面。 – BPRW

回答

0

成員提供商控制的角色,每個用戶擁有。它通常以用戶爲基礎而不是用戶/公司來進行。 您已通過使用[Authorize(Roles = "Admin")]

做正確的事情但是,它聽起來像要檢查當前用戶是否有權訪問當前公司。你可以做到這一點。

[Authorize(Roles = "Admin")] 
public ActionResult EditInfo(string companyId) 
{ 
    if (UserHasAccessToCompany(companyId)) 
    { 
     return View(); 
    } 
    return RedirectToAction("Index"); 
} 

private bool UserHasAccessToCompany(string companyId) 
{ 
    var company = companyRepository.GetCompanyById(companyId); // making the assumption you have a repository for companies 
    return company.Users.Select(u => u.userId).Include(User.Identity.Name); // you can access the current user using the `User` from within the controller 
} 

假設你可能要檢查,如果用戶有權訪問的很多此功能可以移到一個BaseController這樣你就可以隨時隨地訪問它。

+0

這不太對。 我有4個倉庫,它們是: 用戶,角色,公司,UserCompanyRoles 我將編輯問題以使其更清晰。 – BPRW

+0

好吧,請改變'UserHasAccessToCompany'函數中的邏輯,以便返回正確的答案。請記住,通過爲每個公司添加不同的角色,您可能會彎曲會員/角色模式。我懷疑你是否可能在過濾器中做什麼,因爲你需要傳遞一個變量來知道它是哪個公司。 –

0

您並不需要[Authorize(Roles = "Admin")]屬性,因爲您需要用戶可以在公司中以不同的方式看到相同的視圖。但是,如果您添加[Authorize(Roles = "Admin")],用戶將始終將其視爲Admin。

所以,我認爲,你有兩種型號 - User class從會員和Company class這樣

public class Company 
{ 
    public int companyID {get; set;} 
    public straing companyName {get; set;} 
} 

最簡單的解決方案,因爲對我來說,已經第三次參加表的角色:

//In real application userID will be Guid if you use Membership and int if you use SimpleMembership 

    userID companyID role 
     1  2  "Admin" 
     1  3   "User" 

public class MyRole 
{ 
public Guid userID {get; set;} 
public int companyID {get; set;} 
public string roleName {get; set;} 

} 

現在,你可以按如下方式使用它:

public ActionResult CompanyDetails (int id) 
{ 
    var user = Membership.GetUser(User.Identity.Name); 
    Guid currentUserID = (Guid)user.ProviderUserKey; 
    MyRole userRole = db.MyRoles.Where(g=>g.userID = currentUserID & g.companyID = id); // get user role 
    string roleName = userRole.roleName; // get role name 

    bool isAdmin = roleName == "Admin"? true : false; 

    if(isAdmin) 
    { 
    //return as for admin 

    } 
    else 
    { 
    // return as for user 
    } 

} 
+0

這可能是一個解決方案,但這並不意味着我需要爲每個視圖放置過濾代碼?我正在考慮使用自定義的RoleProvider,它可以根據他將訪問的companyId爲用戶返回正確的角色。這樣我就可以在每個視圖中簡單地使用角色篩選的Authorize標籤。但我不確定這是否可行,或者這是一個很好的做法。 – BPRW

+0

@BPRW您可以嘗試基於該過濾來創建自定義操作過濾器:http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-custom-action-filters –