【问题标题】:MVC 3 FormsAuthentication and disabled user accountsMVC 3 FormsAuthentication 和禁用的用户帐户
【发布时间】:2013-02-10 14:19:29
【问题描述】:

我注意到,如果用户仍然登录或拥有持久性 cookie,即使他在数据库中被“禁止”或禁用(用户表标志),用户仍然可以访问所有内容,直到该 cookie 消失或用户退出网站。伟大的安全权利。

所以我正在组合一个 ActionFilterAttribute 来检查这个,对我来说令人不安的是我必须为他的 ActionFilterAttribute 应用到的每个控制器访问数据库。必须有更好的方法来做到这一点,但我还没有找到。

任何想法都会很棒..

【问题讨论】:

    标签: asp.net-mvc-3


    【解决方案1】:

    必须有更好的方法来做到这一点,但我还没有找到。

    不,没有。对不起。如果 disabled/banned user 的概念只存在于您的数据库中,那么除了访问您的数据库之外别无他法。 ASP.NET 仅验证在每个请求上发送的身份验证 cookie 的有效性。它甚至不知道禁用用户的含义,所以你不能期望它做的比它已经做的更多。

    【讨论】:

    • 嘿达林,很高兴再次收到您的来信,先生。创建一个禁用帐户的数据集并缓存它怎么样?每次用户被标记时,我都可以使缓存无效......只是一个想法。然后过滤器可以检查它而不是命中数据库。
    • @CrazyCoderz,当然,将这些信息存储在内存中是一种解决方案。请注意,如果您的应用程序非常成功并且您开始拥有数百万用户(我希望您这样做),您可能会遇到问题。更不用说将此类信息存储在内存中意味着您不能再在网络场中运行,因为 2 个节点不会共享相同的内存。这意味着用户可以在一个 Web 服务器上完全有效,而在另一个 Web 服务器上被禁用。所以如果你走那条路要非常小心,并确保同步缓存。
    【解决方案2】:

    有几个选项:

    1) 可以通过 hook session start 来验证用户认证是否有效。这样,如果用户有一个持久性 cookie,您可以验证用户名并在需要时使 cookie 过期。

    2) 您可以使用基于时间的机制每隔几个请求(每 5 分钟或其他时间)检查用户身份验证状态。您可以使用UserData 字段将lastChecked 时间戳值存储在用户会话中或auth cookie 本身中。这允许您重新检查用户身份验证 cookie 是否需要更频繁地过期,但将数据库调用保持在最低限度。

    【讨论】:

    • 如果他们有一个持久的cookie认证将永远是有效的。我尝试了类似的东西,这就是我注意到的。
    • 我不是在谈论检查身份验证 cookie,我是在谈论访问数据库或其他任何内容并检查标志。如果被禁止或禁用,请使身份验证 cookie 过期。
    • 啊,好的。是的,这就是我目前对过滤器所做的事情,我不喜欢使用属性注入将我的存储库放入过滤器,但它可以工作。
    • 是的,属性总是有点混乱。我很想将其移出并挂钩到授权过程(httpmodule 或全局)。当然,根据您的设置,这可能不会让它变得更干净。
    【解决方案3】:

    MyThis 是我想出的解决方案:

    在 User Account Membership 服务中添加一个函数来返回用户的帐户是否仍然处于活动状态。

    public class UserAccountMembershipService : IMembershipService
    {        
        public bool UserIsActive(Guid userId)
        {
            if (userId == new Guid()) throw new ArgumentException("Value cannot be null or empty.", "userName");
            MembershipUser user = _provider.GetUser(userId, true);
            return user.IsApproved;
        }
    }
    

    按如下方式覆盖 AuthorizeAttribute:

    public class MyAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            IMembershipService membershipService = new UserAccountMembershipService();
    
            //Check to see if the user's account is still active
            bool isActive = false;
            if (httpContext.User.Identity.IsAuthenticated)
            {
                Guid userId = (Guid)Membership.GetUser(httpContext.User.Identity.Name).ProviderUserKey;
                isActive = membershipService.UserIsActive(userId);
            }
    
            if (!isActive)
            {
                //If the user's account is no longer active log him/her out
                IFormsAuthenticationService FormsService = new FormsAuthenticationService();
                FormsService.SignOut();
            }
            //Call the base AuthorizationCore method
            return base.AuthorizeCore(httpContext) && isActive;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 2016-05-03
      • 1970-01-01
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      相关资源
      最近更新 更多