1

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

FormsAuthentication.SetAuthCookie(model.UserName, true)

当我们像这样在 Membership 提供程序中禁用用户时:

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

我们在控制器上使用 Authorize 属性,我知道这在技术上比 Authentication 更 Authorize。但是肯定会出现重叠,所以我试图找出最好的 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
4

2 回答 2

1

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

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

于 2012-04-30T17:51:55.180 回答
1

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

[Authorize(Roles="Login")]

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

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

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

于 2012-04-30T17:58:12.197 回答