阻止AuthorizeAttribute进行缓存

时间:2015-04-27 16:52:01

标签: asp.net-mvc authentication

我有一个自定义AuthorizeAttribute,用于检查用户是否可以访问特定操作:

public class UserCanAccessArea : AuthorizeAttribute
{
    readonly IPermissionService permissionService;

    public UserCanAccessArea() :
        this(DependencyResolver.Current.GetService<IPermissionService>()) { }

    public UserCanAccessArea(IPermissionService permissionService)
    {
        this.permissionService = permissionService;
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        string AreaID = httpContext.Request.RequestContext.RouteData.Values["AreaID"] as string;

        bool isAuthorized = false;

        if (base.AuthorizeCore(httpContext))
            isAuthorized = permissionService.UserCanAccessArea(AreaID, httpContext.User);

        return isAuthorized;
    }
}

代码只检查用户是否已通过身份验证,然后检查应用程序特定数据库中的用户对应条目,以确定用户是否可以访问指定的区域。目前,这只是表格中的“CanAccessAreas”标志。

我遇到的问题是,当管理员更新用户的“CanAccessAreas”标志时,用户仍然无法访问该区域。注意到的行为:

  • 登出/登录并不能解决用户的问题。
  • 在本地运行代码不会重现此行为。
  • 重新发布代码解决了用户的问题,直到更新标志。
  • 每个用户都会看到一个菜单,其中显示了他们可以访问的内容。当管理员更新用户标志时,这会立即更新。

似乎AuthorizeAttribute正在缓存结果,但如果是这种情况,我不确定如何安全地防止这种情况。

1 个答案:

答案 0 :(得分:0)

该构造函数仅被称为when you call GetCustomAttributes,而MVC似乎只调用了一次。

解决方案是在构造函数之外访问您的服务。

例如:

public class UserCanAccessArea : AuthorizeAttribute
{
    public UserCanAccessArea()
    {
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        string AreaID = httpContext.Request.RequestContext.RouteData.Values["AreaID"] as string;

        bool isAuthorized = false;

        if (base.AuthorizeCore(httpContext))
        {
            var permissionService = DependencyResolver.Current.GetService<IPermissionService>();
            isAuthorized = permissionService.UserCanAccessArea(AreaID, httpContext.User);
        }

        return isAuthorized;
    }
}

我没有使用Unity的经验,但是使用Property Injection也可以实现@pjobs的评论。