2016-06-07 56 views
1

示例:在MVC(ASP)中的相同数据上实现多个角色

我们有两种用户类型。

  • SupplierUser
  • FactoryUser

他们用基本相同的数据,但一般FactoryUsers可以编辑更多的信息比SupplierUser两个接口。

使用ASP.NET 4.5,我正在使用MVC实现所有这些。

一些总结的用例:(假设登录)

FactoryUser:

  • 可编辑的邮件页面,该页面显示供应商的最新公告。
  • 订单确认页面和订单查看页面。
  • 供应商编辑页面(用于更新地址的多个供应商等)

SupplierUser: - 可以看到特定工厂的消息。 - 可以创建订单,发送和查看。 - 可以编辑他们自己的信息

正如你所看到的,这只是许多具有不同权限的信息编辑。我的问题是,我应该在哪里开始分色?

至于:

  1. 模型 - 我觉得这一个保持为一个与数据库
  2. 的ViewModels - 我写的每个角色不同的看法?如果是这样,2个文件/类?
  3. 控制器 - 相同,我可以编写不同的功能吗?类?如果是这样,那么[授权角色]有什么意义,只是为了防止未经授权的访问&不打算分裂?
  4. 观点 - 我是否尝试对大多数部分使用相同的视图,并且只是包含关于他们是否具有“编辑”按钮的逻辑?
  5. 部分视图 - 它们可以用于可能或不可能位于视图上的“编辑”按钮吗?
  6. 查看布局 - ?
  7. 过滤器 - 我可以做一些花哨的逻辑,并将所有内容放在完全2个不同的文件夹中(整个MVC),然后将其分割为路由/授权级别
  8. 路由 - ?

在上面的每一个,我可以看到根据用户类型拆分逻辑的可能性。但是,当然,我想以最简单,最健全的方式来做到这一点。

是否有一些文件指定应该如何完成,或者是否有任何聪明的人在那里做过这些事情,并遇到过所有问题?

感谢 (第一个问题!)

+1

{授权]只允许或不允许访问动作/控制器。您可以在视图中检查用户角色,并根据角色隐藏或显示不同的操作, –

回答

2

的一种方式做,这是打造特色。例如View Orders, Create Order, Update Order, Delete Order

这些features将被分配到一个Role - 和角色可以被分配到一个User

所以DB会是这个样子:

enter image description here

现在,当用户登录后,读取分配给用户的所有功能并将它们保存在会话中(创建SessionHandler类)。 UserDTO类

样品 SessionHandler

public class SessionHandler 
{ 
    private const string SessionKey = "UserSession"; 

    public static UserDTO UserSession 
    { 
     get 
     { 
      return HttpContext.Current.Session[SessionKey] != null 
         ? (UserDTO)HttpContext.Current.Session[SessionKey] 
         : null; 
     } 
     set { HttpContext.Current.Session[SessionKey] = value; } 
    } 
} 

所以在你的控制器

public class UserDTO 
{ 
    public int UserId {get;set;} 
    public List<string> Features {get;set;} 
} 

// Login Function - You can call from Controller 
public UserDTO Login(string username, string password) 
{ 
var user = dbContext.Users.FirstOrDefault(s => s.Username == username && s.Password == password); 

if(user == null) return null; // login failed 

var model = new UserDTO() 
{ 
    UserId = user.UserId, 
    Features = user.Role.Features.Select(s => s.FeatureName).ToList() 
}; 


return model; 

} 

样品致电Login功能和SessionHandler

[HttpPost] 
public ActionResult Login(LoginModel model) 
{ 
    var user = Login(model.username, model.password); 

    if(user == null) return View(model); 

    SessionHandler.UserSession = user; 

    // TODO: redirect to Home Page - after login 

    return RedirectToAction("Index", "Home"); 
} 
分配给

然后,您可以在视图中执行的操作是检查用户是否可以执行特定操作,例如,如果你是查看订单页面上 - 你可以隐藏创建订单按钮,如果用户没有权限:

@model WhateverDTO 

    // Check if user has Create Order Feature in Role 

    @if (SessionHandler.UserSession.Features.Contains("Create Order")) 
    { 
// Yes, User has permission - then Render the Button 

    <button> Create Order </button> 

    } 

您也可以在控制器(服务器端)添加检查 - 这将提供额外的安全性您应用程序,使用该授权属性:

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (httpContext == null) 
      throw new ArgumentNullException("httpContext"); 
     if (httpContext.Session == null) 
      return false; 

     // Checking Authenticaiton 
     var userSettings = SessionHandler.UserSession; 
     if (userSettings == null) 
      return true; 

     //Checking Authorization 
     if (Roles.Length == 0) 
      return true; 


     var actionFeatures = Roles.Split(','); 
     if (!actionFeatures.Any(s => userSettings.Features.Contains(s))) 
      throw new UnauthorizedAccessException("You do not have permission to perform this action."); 
     return true; 
    } 
} 

,然后装点您的操作,

[CustomAuthorize(Roles = "Create Order")] 
// Pass feature name for Roles - if user doesn't have permission to Create Order - the "You do not have permission to perform this action." exception will get thrown 
public ActionResult CreateOrder() 
{ 
    return View(new CreateOrderDTO()); 
} 

[HttpPost] 
[CustomAuthorize(Roles = "Create Order")] 
// Pass feature name for Roles - if user doesn't have permission to Create Order - the "You do not have permission to perform this action." exception will get thrown 
public ActionResult CreateOrder(CreateOrderDTO model) 
{ 

    return View(model); 
} 

关于上述方法的好处 - 是,你可以添加尽可能多的用户角色因为你需要 - 而不需要改变代码。


模型 - 我觉得这一个保持为一个与数据库

模型是相同的 - 相同的DB同型号

的ViewModels - 我写的每个角色不同的看法?如果是这样,2个文件/类?

不,不要复杂的事情 - 用同一视图模型/ DTO

控制器 - 一样,不用我写不同的功能?类?如果是这样,那么[授权角色]有什么意义,只是为了防止未经授权的访问&不打算分裂?

无需单独行动/观点或控制器

意见 - 我尝试使用的大部分地区相同的看法,只是不知何故包括逻辑,如果他们有“编辑”按钮或不?

是,使用同样的观点 - 隐藏/基于用户角色/显示操作功能

局部视图 - 它们可以被用于“编辑”按钮,可能会或可能不会对看法?

无需为按钮

视图布局部分观点 - 过滤器 - 我可以做一些花哨的逻辑,并将所有内容放在完全2个不同的文件夹中(整个MVC),然后在路由/授权级别分割它 路由 - ?

+0

您可以给我一点方向,理想情况下应放置这些文件的位置吗? (MVC结构明智) – Worthy7

+0

我已经实现了这个,它的工作原理,谢谢:)让我知道我应该把类放在命名空间/文件夹/文件 – Worthy7

+1

@ Worthy7完全依赖于你的应用程序的体系结构 - SessionHandler应该被添加到MVC Web应用程序的子文件夹中,例如助手。除此之外,如果您有一个单独的DTO Enums项目,请将它们放在那里 - 否则将它们添加到MVC Web项目中的子文件夹中。 –

相关问题