8

我有一个带有存储库层的 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在每个动作中构建?或者在存储库层处理它是一个坏主意?

4

3 回答 3

5

或者在存储库层处理它是一个坏主意?

我认为Controller是您授权的更好地方。让存储库成为数据的网关,控制器成为应用程序的看门人。我希望尽可能早地在生命周期中看到授权/身份验证逻辑。

于 2013-02-15T19:27:58.560 回答
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();
    }
}
于 2013-02-15T19:26:27.947 回答
1

来自@BigDaddy 和@ChrisPratt 的好建议。

我最终通过创建一个基本控制器来解决这个问题,类似于这个答案。我的基本控制器类如下所示:

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引用了当前经过身份验证的用户。

于 2013-02-15T19:58:21.007 回答