MVC 3 FormsAuthentication and disabled user accounts
I have noticed that if a user is still logged in or has a persistent cookie, even if he gets "banned", or disabled in the database (Users Table flags), the user can still access everything until that cookie goes away or the user logs out of the site. Great security right.
So I am putting together a ActionFilterAttribute that checks for this, the disturbing thing for me is I have to hit the database for every controller that his ActionFilterAttribute is applied to. There has to be a bette开发者_JS百科r way of doing this but I have not found one yet.
Any ideas would be awesome..
There has to be a better way of doing this but I have not found one yet.
No there isn't. Sorry. If the notion of disabled/banned user exists only in your database there is no other way but hitting your database. ASP.NET only verifies the validity of the authentication cookie which is sent on each request. It doesn't even know what a disabled user means so you cannot expect it do more than it already does.
There are a few options:
1) You can validate whether the user authentication is valid by hooking session start. This way if the user has a persistent cookie, you can validate the username and expire the cookie if needed.
2) You can use a time based mechanism to check the user auth status every few requests (every 5mins or whatever). You could store the lastChecked
timestamp value in the user session or in the auth cookie itself using the UserData
field. This allows you recheck if the user auth cookie needs to be expired more frequently, but keeps database calls to a minimum.
MyThis is the solution I came up with:
In the User Account Membership service add a function to return whether the user's account is still active.
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;
}
}
Override the AuthorizeAttribute as follows:
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;
}
}
精彩评论