我有一个带有存储库层的Windows身份验证的MVC应用程序。控制器与数据库的所有交互都是通过存储库完成的。每个控制器都有对存储库的引用:
public class PostController : Controller
{
private Repository db = new Repository();
[HttpPost]
public ActionResult DeletePost(int id)
{
// Authorize that the user is allowed to delete this post...
db.DeletePost(id);
}
}
我的问题是,是否有一种将授权逻辑移动到存储库层的好方法。我希望Repository.DeletePost()
函数拒绝删除未经过身份验证的用户创建的帖子。问题是我的存储库不知道经过身份验证的用户是谁。控制器知道(通过Controller.User
)。
将Controller.User
传递给Repository
构造函数不起作用,因为在调用构造函数时,Controller.User
显然没有定义。
如何通知Repository
经过身份验证的用户是谁?在每个动作中构建Repository
是否最好?或者在存储库层中处理它是一个坏主意?
答案 0 :(得分:4)
或者在存储库层中处理它是不是一个坏主意?
我认为Controller是一个更好的授权地点。让存储库成为数据的网关,控制器成为应用程序的守门员。我期望在生命周期的早期看到授权/认证逻辑。
答案 1 :(得分:1)
做一些像:
db.DeletePostForUser(id, User.Identity.UserId);
然后在您的存储库中:
public void DeletePostForUser(int id, int userId)
{
var post = context.Posts.SingleOrDefault(m => m.PostId == id && m.User.UserId == userId)
if (post != null)
{
context.Posts.Remove(post);
context.SaveChanges();
}
}
答案 2 :(得分:1)
@BigDaddy和@ChrisPratt的好建议。
我最终通过创建一个类似于this answer的基本控制器来解决这个问题。我的基本控制器类看起来像:
public class BaseController : Controller
{
private ILog _log;
private Repository _db;
protected Repository Db
{
get
{
return _db ?? (_db = new Repository(User));
}
}
protected ILog Log
{
get
{
return _log ?? (_log = LogManager.GetLogger(this.GetType()));
}
}
}
我的所有控制器都继承自此类,并且具有对延迟加载的Repository
的内置访问权限,该{{1}}具有对当前经过身份验证的用户的引用。