Asp.net 在MVC(ASP)中对同一数据实现多个角色
例如: 我们有两种用户类型Asp.net 在MVC(ASP)中对同一数据实现多个角色,asp.net,asp.net-mvc,Asp.net,Asp.net Mvc,例如: 我们有两种用户类型 供应商用户 工厂用户 它们都与基本相同的数据交互,但一般来说,Factory用户可以编辑比供应商用户多得多的信息 使用ASP.NET4.5,我将使用MVC实现所有这些 一些总结用例:(假设已登录) FactoryUser: 可编辑消息页面,显示供应商的最新公告 订单确认页面和订单查看页面 供应商编辑页面(用于更新多个供应商的地址等) 供应商用户: -可以查看来自特定工厂的消息。 -可以创建订单、发送和查看。 -可以编辑自己的信息 正如您所看到的,这只是大量使用
- 供应商用户
- 工厂用户
- 可编辑消息页面,显示供应商的最新公告
- 订单确认页面和订单查看页面
- 供应商编辑页面(用于更新多个供应商的地址等)
(第一个问题!)一种方法是创建功能。e、 g
查看订单、创建订单、更新订单、删除订单
这些功能
随后将分配给角色
——并且该角色可以分配给用户
因此,DB将如下所示:
现在,当用户登录时,您将读取分配给用户的所有功能,并将它们保存在会话中(创建SessionHandler类)
UserDTO类的示例
public class UserDTO
{
public int UserId {get;set;}
public List<string> Features {get;set;}
}
因此,在控制器中调用Login
函数,并在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; }
}
}
[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>
}
然后装饰你的行为
[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相同的模型 视图模型-我是否为每个角色编写不同的视图?如果是,则为2个文件/类? 不,不要使事情复杂化-使用相同的ViewModel/DTO 控制器-相同,我是否编写不同的函数??上课?如果是这样的话,那么拥有[授权角色]只是为了防止未经授权的访问,而不是为了分裂,这有什么意义呢? 不需要单独的操作/视图或控制器 视图-我是否尝试对大多数零件使用相同的视图,并以某种方式包含关于它们是否有“编辑”按钮的逻辑? 是,使用相同的视图-根据用户角色/功能隐藏/显示操作 局部视图-它们是否可用于视图上的“编辑”按钮? 按钮不需要局部视图 查看布局-? 过滤器-我可以做一些奇特的逻辑,将所有内容放在完全不同的2个文件夹(整个MVC)中,然后在路由/授权级别将其拆分 路由-?
否{Authorize]只允许或不允许访问操作/控制器。您可以检查视图中的用户角色,并根据角色隐藏或显示不同的操作,您能告诉我这些文件理想的放置位置吗?(MVC结构)我已经实现了这一点,它可以工作了,谢谢:)让我知道我应该在哪里放置与命名空间/文件夹相关的类/file@Worthy7这完全取决于应用程序的体系结构-SessionHandler应该添加到MVC Web应用程序的子文件夹中,例如Helpers。如果您有单独的DTOs枚举,然后将它们放在那里-否则将它们添加到MVC Web项目的子文件夹中。
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);
}