我正在尝试使用Entity Framework和Code First方法的ASP.NET MVC。我只是想问一下,是否有更好的方法来处理这种用户限制的实现?
我制作一个客户可以用来查看与他们相关的数据的门户网站。这基于ASP.NET身份。因此,在每个控制器上,我都这样做以获得当前用户:
var user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());
然后我将其添加到上下文查询中:
//Query the context and get all stuff from this users companies.
var restaurants = from p in db.Restaurants orderby p.Name where p.CompanyId == user.CompanyId select p;
var all= restaurants.ToListAsync();
return View(await all);
这是一个正常的实现,还是有比将其放在每个控制器操作上更好的方法?
答案 0 :(得分:1)
嗯,我想是正常的。但是,这实际上并不是由用户限制,而是由用户所属的公司限制。如果这是你想要的,那就没关系,但要注意,属于同一家公司的任何用户也都有权访问。
如果您确实想要仅限用户限制,则需要在该对象上为该用户提供外键。此时,您将以相同的方式处理查询,仅按用户ID进行过滤,而不是公司ID。此时您也不需要实际获取用户对象,因为您需要User.Identity.GetUserId()
所需的所有信息。
var userId = User.Identity.GetUserId();
var restaurants = from p in db.Restaurants orderby p.Name where p.UserId == userId select p;
注意:您需要首先将用户ID实际保存到变量,因为方法User.Identity.GetUserId()
不能转换为SQL。这是一个小问题,但如果您尝试直接在查询中使用它,则会遇到异常。
答案 1 :(得分:0)
过去我使用类似模型的东西来翻译我的主要对象,例如:
public class IPrincipalModelBinder: IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null) throw new ArgumentNullException("controllerContext");
if (bindingContext == null) throw new ArgumentNullException("bindingContext");
IPrincipal user = controllerContext.HttpContext.User;
return user;
}
}
然后您可以执行以下操作:
[Authorize]
public ActionResult ActionName(IPrincipal loggedInUser)
{
var user = // get from repository
// do stuff
return View();
}
您在Global.asax
Application_Start
注册了ModelBinder
ModelBinders.Binders[typeof(IPrincipal)] = new IPrincipalModelBinder();
答案 2 :(得分:0)
你可以使用基于经理角色的安全功能更加实用,你说用户的许可,他只访问他允许的控制器。请参阅以下示例:
[Authorize(Roles="Restaurants")]
public ActionResult Index()
{
// Do stuff here
return View();
}
例如,在此方法中,您将只能访问具有“餐馆”角色的用户
http://www.dotnetcurry.com/aspnet-mvc/1102/aspnet-mvc-role-based-security