views:

49

answers:

4

Hi,

I am using database with a list of username/passwords, and a simple web form that allows for users to enter their username/password.

When they submit the page, I simply do a stored procedure check to authenticate. If they are authorised, then their user details (e.g. username, dob, address, company address, other important info) are stored in a custom User object and then in a session. This custom User object that I created is used throughout the web application, and also in a sub-site (session sharing).

My question/problems are:

  1. Is my method of authentication the correct way to do things?

  2. I find users complaining that their session have expired although they "were not idle", possibly due the app pool recycling? They type large amounts of text and find that their session had expired and thus lose all the text typed in. I am uncertain whether the session does really reset sporadically but will Forms Authentication using cookies/cookiless resolve the issue?

  3. Alternatively should I build and store the User Object in a session, cookie or something else instead in order to be more "correct" and avoid cases like in point #2.

  4. If I go down the Forms Authentication route, I believe I cannot store my custom User object in a Forms Authentication cookie so does it mean I would store the UserID and then recreate the user object on every page? Would this not be a huge increase on the server load?

Advice and answers much appreciated.

L

A: 

My advice would be to use asp.net membership and roles (Microsoft). It is a very good security solution - login security, roles (permissions) and is stored in a SQLServer database (not sure if it can be stored elsewhere).

I use it on my site and you can use membership controls straight out of the box (login forms, change password, etc.) or you can roll your own.

The only tricky bit I found was setting up the membership tables, views and stored procs in my dB (you download a dB script), but really it was fairly straightforward to implement.

Here's a link to asp.net membership and roles

adrianos
Thanks for the recommendation. The problem in this is that we store the username and password in a seperate (already live database) and so I think this is not suitable for me I think.
Ichirichi
A: 

You can use ASP.NET Membership, Roles, Forms Authentication, and Security Resources I will give an example using c#

For reference Forms Authentication in ASP.NET 2.0

 //code for checking user name & password 
protected void btnlogin_Click(object sender, EventArgs e)
{
    try
    {
        if (txtUserName.Text.Trim() != "" && txtPassword.Text.Trim() != "")
        {
            User obj = objUser.UserAuthenticate(txtUserName.Text.Trim(), txtPassword.Text.Trim());
            if (obj != null)
            {
                //To set AuthenticationCookie of usertype "User"
                SetAuthenticationCookie("User", obj.UserID.ToString(), obj.DisplayName);

                HttpCookie usercookie = new HttpCookie("LoginTime");
                usercookie.Value = DateTime.Now.ToString();
                Response.Cookies.Add(usercookie);
                HttpCookie namecookie = new HttpCookie("LoginName");
                namecookie.Value = obj.DisplayName;
                Response.Cookies.Add(namecookie);



            }
            else
            {
                lblMsg.Text = "Invalid Username or Password.";
            }
        }
        else
        {
            //lblMsg.Visible = true;
        }
    }
    catch (Exception ex)
    {
        //lblMsg.Visible = true;
        throw ex;
    }
}

private void SetAuthenticationCookie(string role, string userid, string name)
{

string userdata = "logintype=user|role=" + role + "|email=" + txtUserName.Text.Trim() + "|name=" + name;

    FormsAuthenticationTicket faTicket = new FormsAuthenticationTicket(1, userid,
       DateTime.Now, DateTime.Now.AddHours(+1),
                                           false, userdata);

    HttpCookie authCookie = new HttpCookie( FormsAuthentication.FormsCookieName,//"[email protected]",
                                            FormsAuthentication.Encrypt(faTicket));

    authCookie.Expires = faTicket.Expiration;
    Response.Cookies.Add(authCookie);


}

    //code inside global.asax.cs
    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        if (Context.User != null && Context.User.Identity is FormsIdentity && Context.User.Identity.IsAuthenticated)
        {
            FormsAuthenticationTicket faTicket = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value);

            string[] userdata = faTicket.UserData.Split("|".ToCharArray());
            string logintype = "";
            string email = "";
            string uname = "";
            string roleString = "";
            foreach (string s in userdata)
            {
                string keyname = s.Split("=".ToCharArray())[0];
                if (keyname == "logintype")
                {
                    logintype = s.Split("=".ToCharArray())[1];
                }
                else if (keyname == "role")
                {
                    roleString = s.Split("=".ToCharArray())[1];
                }
            }
            string[] rolesArray = roleString.Split(";".ToCharArray());
            Context.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(faTicket), rolesArray);
        }
    }   
amexn
A: 
  1. It doesn't really care whether you use your own authentication system, or the default membership providers when using such a simple scenario.
  2. You should avoid using the InProc session state when the app might recycle some times a day. Rather store your session into a database (SqlSessionState) or use a StateServer. Then the application pool can recycle all day without interferring with your sessions. Setting the session timeout to 60 minutes or something, will solve the remaining issues. Never use cookieless sessions (unless you know what you're doing), as they make it way too easy to steal one's session.
  3. Just store it into the session (or profile if you use the default membership provider). Not only is a cookie easily readible, it is also limited to 4 KB.
  4. No, you will have a profile where all the user information is stored. It doesn't really matter whether you use forms authentication or a custom system that stores it's data into SqlSessionState. The membership provider will store the Profile ID into a cookie, same as the session state will save the Session ID into a cookie.
Jan Jongboom
Thank you so much for this :-)I have setup my website to store sessions in SQL DB.Do you know roughly how much memory is used and whether I should be concerned?Thanks
Ichirichi
A: 

Just to touch on point #4 - it would be more efficient memory-wise to not store everyone's "User" object in memory, and re-create the object each HTTP request. This way you also re-verify the login details-- what if someone's account is compromised and the actual user changes their password to try and protect their account, but the "bad user" has already logged in? Under your security mechanism, the "bad user" can keep browsing away since the user data is cached and not re-verified each postback.

Nicholas H