0

I have created login page and i want to verify the users if they have access or not. I have done most of the work but just need couple of things here: 1) if user is validated, then i want to redirect to Home.aspx page 2) After the user is validated i want to be able to save the user id in a session so they don't have to login every time if they are redirected to another page. Basically, once they login successfully they should be able to navigate other pages in the application. thanks. here is the code behind:

protected void ValidateUser3(object sender, EventArgs e)
        {
            int userId = 0;
            string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
            using (SqlConnection con = new SqlConnection(constr))
            {
                using (SqlCommand cmd = new SqlCommand("Validate_User"))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@Username", txtUID.Text.Trim());
                    cmd.Parameters.AddWithValue("@Password", txtPWD.Text.Trim());
                    cmd.Connection = con;
                    con.Open();
                    userId = Convert.ToInt32(cmd.ExecuteScalar());
                    con.Close();
                }
                switch (userId)
                {
                    case -1:
                        logLbl.Text = "Username and/or password is incorrect.";
                        break;
                    case -2:
                        logLbl.Text = "Account has not been activated.";
                        break;

                }
            }
        }

Here is my stored proc:

ALTER  PROCEDURE [dbo].[Validate_User]
    @Username NVARCHAR(20),
    @Password NVARCHAR(20)
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @UserId INT, @LastLoginDate DATETIME

    SELECT @UserId = UserId, @LastLoginDate = LastLoginDate 
    FROM myTable WHERE Username = @Username AND [Password] = @Password

    IF @UserId IS NOT NULL
    BEGIN
        IF NOT EXISTS(SELECT UserId FROM [Main].[UserActivation] WHERE UserId = @UserId)
        BEGIN
            UPDATE myTable.[dbo].[UserProfile]
            SET LastLoginDate =  GETDATE()
            WHERE UserId = @UserId
            SELECT @UserId [UserId] -- User Valid
        END
        ELSE
        BEGIN
            SELECT -2 -- User not activated.
        END
    END
    ELSE
    BEGIN
        SELECT -1 -- User invalid.
    END
END
moe
  • 4,609
  • 37
  • 117
  • 183

1 Answers1

1

First up I'd look at tightening that security. Don't save passwords in your database, not even hashed ones. And follow krillgar's advice in the comments to your question :)

What you want to do with each user account is create a unique salt code - a random value, with a minimum of 8 in length (the more the better naturally): See here for creating a salt code. You want to save that in your database in the users table. So you'll have something like a table structure like: UserId, UserName, PassString, SaltCode, Active

Pick a Hashing method; MD5 or SHA1 are typical examples. When the password is created you take the username, merge it into the password, add your salt code then Hash it. This will create a unique string - that's what you save into your database in the PassString field.

So when someone logs in you take the username and password, look up the user record, get the salt code. Hash it all together then compare the two hashed strings.

Check out this section on Stack Overflow: How to hash a password

This makes your passwords irreversible without all segments of the data in other words; the password the user enters to login is the missing key to the puzzle. If someone is somehow able to get the data out of your table they'll have to a ton of work to crack a user's account.

so to now answer your actual question :)

Just like you have with your Stored Procedure, when the user is successfully matched return a value such as 1. I would suggest you keep your return codes and userid value separate so there's less ambiguity in your code. You got a choice with your SP, you can either return the userid back in with the return code on a Select statement ie Select 1, @UserId or you can use an OUTPUT parameter, here's a fairly decent example: Using stored procedure output parameters in C# (I'd favour the latter).

Now working with what you've got (and by that I mean, not telling you to go off an use System.IdentityModel.Service, UserPrinciple and the likes)...

Once that successful login has been acknowledged by your SP, use a session variable in the following manner, Session variables are kept server side so unless your server is compromised you'll be ok:

Session["UserId"] = userId;
Response.Redirect("Home.aspx");

Now on pages like Home.aspx you just need some code along the lines of;

bool userLoggedIn = false;
if (Session["User"] != null) //check the session variable is actually valid
{
    if (!String.IsNullOrEmpty(Session["User"]))
    {
        userLoggedIn = true;
    }
}

if (!userLoggedIn)
{
    Response.Redirect("login.aspx");
}

Though it would be a lot wiser to create a class in the App_Code folder to handle this, last thing you want is duplicated code all over your site.

The issue you'll run into is giving user's rights. I'm not clear from your question but I got the impression you wanted a binary login, ie: if a user is authenticated they have access, plain and simple. If you're after segmented security; controlling what each user can or cannot do then you need to be looking down the route of Claims based security, here's an example of that to get you thinking: http://www.codeproject.com/Articles/2905/Role-based-Security-with-Forms-Authentication

I hope that helps and wasn't too long a read :)

Community
  • 1
  • 1
Hugo Yates
  • 2,008
  • 2
  • 24
  • 24