我注意到如果用户仍然登录或拥有持久性cookie,即使他在数据库中被“禁止”或禁用,或者在数据库中禁用(用户表标记),用户仍然可以访问所有内容,直到cookie消失为止或者用户退出网站。很高的安全权。
所以我正在整理一个ActionFilterAttribute来检查这个,对我来说令人不安的是我必须为他的ActionFilterAttribute应用的每个控制器点击数据库。必须有一个更好的方法来做到这一点,但我还没有找到一个。
任何想法都会很棒......
答案 0 :(得分:1)
必须有更好的方法来做到这一点,但我还没有找到。
不,没有。抱歉。如果禁用/禁止用户的概念仅存在于您的数据库中,则除了命中您的数据库之外别无他法。 ASP.NET仅验证在每个请求上发送的身份验证cookie的有效性。它甚至不知道被禁用的用户意味着什么,所以你不能指望它比现在做得更多。
答案 1 :(得分:1)
有几个选择:
1)您可以通过挂钩会话启动来验证用户身份验证是否有效。这样,如果用户具有持久性cookie,您可以验证用户名并在需要时使cookie过期。
2)您可以使用基于时间的机制来检查每隔几个请求(每5分钟或其他任何时间)的用户身份验证状态。您可以使用lastChecked
字段将UserData
时间戳值存储在用户会话或auth cookie本身中。这允许您重新检查用户auth cookie是否需要更频繁地过期,但是将数据库调用保持在最低限度。
答案 2 :(得分:1)
MyThis是我提出的解决方案:
在“用户帐户成员资格”服务中,添加一个函数以返回用户的帐户是否仍处于活动状态。
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;
}
}