开发者

Deleted User logged in even after deleting on the other broswer

var query = from p in AdminModelContext.Users
            where p.UserName == model.UserName && p.Password == encryptPassword 
            && p.IsDeleted == false
                                select p;
            IList<Users> userList = query.ToList();

if (userList.Count() > 0)
{
    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

    if (CheckUrl(returnUrl))
    {
        return Redirect(returnUrl);
    }

    SetRoleForUser(userList[0].RolesId);
    LoggerService.Info(string.Format("Login Successful for the user : {0}", 
        model.UserName));

    return RedirectToAction("Index", "Home");
}

I am using the following code to Login through my website. The problem that I am facing is when I logged in with a user on a specific browser and at the same time login with a different user on a different browser, and then I delete the user(logged in on the other browser). Still I am able to navigate through the pages with the deleted user logged in.

I am n开发者_StackOverflowot finding a fair solution to put authentication logic on every page. My website is in MVC model and using Form based authentication.

Please suggest how can I put the logged in user session validation and achieve this.


None of the answers so far actually acknowledge the question.

Lets look at the control flow:

User A enters log in page, supplies valid credentials
User A is issued Ticket A.

User B enters site, supplies valid credentials.
User B is issued Ticket B.

User B then revokes User A's access CREDENTIALS.

At this point nothing happens to Ticket A. Because the Ticket is independent on the credentials. When Ticket A expires they will then be required to present their credentials and it will fail login.

So what you've noticed that kicking a live user out of your site is actually pretty hard. As you've realized the ONLY solution is to have authentication logic on EVERY request. That unfortunately is really heavy.

In the login system I built I handled this aspect by creating 2 tickets, 1 ticket that's stored in the Forms Auth ticket as normal that has a big duration, and a ticket that's stored in HttpRuntime.Cache, I set the cache expiration to 15 minutes on this ticket.

On every page request I check to see whether a user has a ticket in the cache (based off their Forms Auth ticket information), at this point if they have no ticket I do a user data refresh and poll the user database. If the user has become suspended or deleted they will be logged out at then.

Using this method I know that my site can disable a user and within 15 minutes that user will be barred from the site. If I want them immediately barred I can just cycle the app config to clear the cache and FORCE it to happen.


Normally if you have the [Authorize] attribute defined for an Controller or an Action the Authentication is checked on every post back.

The build in MembershipProvider handles all that for you. But it seems you are using your own user Database. Then you have to implement your own MembershipProvider, IPrincipal and MembershipUser and have this added to your Web.config replacing the default one.

More you'll find here how to implement your own MembershipProvider: http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx

My suggestion is to create an empty MVC project and have a look at the default authentication mechanism. And if your building a new Application with a new Database, try to use the default authentication.

Your validateUser function in your own MembershipProvider could look like this.

public override bool ValidateUser(string username, string password)
{
    bool isValid = false;
    bool isApproved = false;
    string pwd = "";

    using (AdminModelContext db = new AdminModelContext())
    {
        var user = db.Users.FirstOrDefault(u => u.UserName == username);
        if (user != null)
        {
            pwd = user.Password;
            isApproved = user.IsApproved;

            if (CheckPassword(password, pwd))
            {
                if (isApproved)
                {
                    isValid = true;

                    user.LastLoginDate = DateTime.Now;
                    user.LastActivityDate = DateTime.Now;

                    try
                    {
                        db.SubmitChanges();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }
                }
            }
            else
            {
                UpdateFailureCount(username, "password");
            }
        }
    }

    return isValid;
}


I see the problem now. I dont know how this works in MVC, but by using Authenticate_Request, you can validate if the user is still valid. The business logic may also double check if the user is still valid. But as far as I know, there is no way of iterating all the open sessions and killing the requierd ones, even in that case, the authorization cookie should be double checked on Session_Start event. Another options is adding a global invalidated_users list on the application, and then checking that user against the invalid list. This list should only contain users that are invalidated after the application has restarted.

Link for Reading All Users Session:

http://weblogs.asp.net/imranbaloch/archive/2010/04/05/reading-all-users-session.aspx

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜