如何在使用ASP Forms Persistent Cookie / Ticket时禁用用户?

时间:2012-04-30 17:42:40

标签: asp.net asp.net-mvc-3 forms-authentication

我在MVC 3站点中使用Forms Auth和ASP Universal Membership Provider。为了方便用户,我们坚持使用cookie。

FormsAuthentication.SetAuthCookie(model.UserName, true)

当我们在会员提供者中禁用用户时,如下所示:

memUser.IsApproved = model.IsActive;
provider.UpdateUser(memUser);

如果他们有cookie,他们仍然可以进入该网站。这类似于这篇文章中描述的内容:http://stackoverflow.com/questions/5825273/how-do-you-cancel-someones-persistent-cookie-if-their-membership-is-no-longer-v

我们在控制器上使用授权属性,我知道这在技术上比授权更多授权。但肯定会超载,所以我试图弄清楚什么是最好的MVC方式来检查用户实际上没有被禁用?自定义AuthorizeAttribute,根据成员资格数据库检查用户?一个明显的设置/方法我没有使用Forms auth来使票证无效?

更新

这基本上就是我的目标 - 我们使用自定义权限被拒绝页面,我们使用它来更好地告知用户他们没有权利而他们没有登录。我添加了IsApproved检查。将属性放在Controller或Action上时会调用AuthorizeCore,如果返回false则调用HandleUnauthorizedRequest。

public class CustomAuthorization : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated || !Membership.GetUser(filterContext.HttpContext.User.Identity.Name).IsApproved)
        {
            filterContext.Result = new HttpUnauthorizedResult();

            // in the case that the user was authenticated, meaning he has a ticket, 
            // but is no longer approved we need to sign him out 
            FormsAuthentication.SignOut();
        }
        else
        {
            var permDeniedRouteVals = new System.Web.Routing.RouteValueDictionary() { { "controller", "MyErrorController" }, { "action", "MyPermissionDeniedAction" }, { "area", null } };
            filterContext.Result = new RedirectToRouteResult(permDeniedRouteVals);
        }
    }

    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        // since persisting ticket,
        // adding this check for the case that the user is not active in the database any more
        return base.AuthorizeCore(httpContext) && Membership.GetUser(httpContext.User.Identity.Name).IsApproved; 
    }
}

用法:

[CustomAuthorization()]
public class MyController

2 个答案:

答案 0 :(得分:1)

嗯,无论如何你都要检查数据库,唯一的问题是你想怎么做。是的,您可以创建自定义授权属性,或者您可以在ControllerBase中为OnAuthorize覆盖编写一些代码,或者您可以在Application_AuthenticateRequest中执行此操作。您可以通过多种方式执行此操作,具体取决于哪种方法最适合您。

当然,最好的方法是不使用持久性票证,如果这对你来说是一个问题。

答案 1 :(得分:1)

我几乎总是使用Roles和RolesProvider,即使只有一个名为“Login”的角色 - 部分是针对此问题。这样,您的Authorize属性可能如下所示:

[Authorize(Roles="Login")]

Login代表所有“有效”帐户必须能够登录的基本“角色”;每个受保护的操作至少受此保护。

这样,只需删除“登录”角色就会有效地禁用用户... 因为,在我的角色提供程序中,我正在检查登录用户对数据库或服务器本地的角色等效。

在您的情况下,您的“登录”角色可以简单地解析为检查用户模型上的IsApproved字段。