2015-01-31 81 views
0

我已經創建了登錄頁面,我想驗證用戶是否有權訪問。我已經完成了大部分工作,但只需要幾件事情在這裏: 1)如果用戶驗證,然後我想重定向到Home.aspx頁面 2)在用戶驗證後,我希望能夠保存用戶身份證在會話中,所以他們不必每次都登錄,如果他們被重定向到另一個頁面。 基本上,一旦他們成功登錄,他們應該能夠瀏覽應用程序中的其他頁面。謝謝。 這裏是後面的代碼:在Asp.net中創建登錄和驗證用戶

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; 

       } 
      } 
     } 

這裏是我的存儲過程:

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 
+0

我不會說該帳戶尚未激活。這會讓任何發送垃圾郵件的人知道他們的用戶名無效。 – krillgar 2015-01-31 18:43:46

+0

此外,你正在做的這個WebForms或MVC? – krillgar 2015-01-31 18:48:04

+0

我正在使用WebForms .. – moe 2015-01-31 19:28:35

回答

1

第一了,我想看看收緊的安全。不要將密碼保存在數據庫中,甚至不要保存密碼。並按照krillgar的建議在您的問題的意見:)

你想要做的每個用戶帳戶是創建一個獨特的鹽代碼 - 隨機值,至少8長度(越自然越好) :See here for creating a salt code。您想要將其保存在用戶表中的數據庫中。因此,您將擁有類似如下的表結構:UserId,UserName,PassString,SaltCode,Active

選擇散列方法; MD5SHA1是典型的例子。當你創建密碼時,你需要輸入用戶名,將其合併到密碼中,然後添加你的鹽碼然後哈希它。這將創建一個唯一的字符串 - 這就是您在PassString字段中保存到數據庫中的內容。

所以當有人登錄時,您需要輸入用戶名和密碼,查找用戶記錄,獲取鹽碼。將它們全部散列在一起,然後比較兩個散列字符串。

查看此部分對堆棧溢出:How to hash a password

這使得你的密碼不可逆的無換句話說數據的所有部分;用戶輸入的用於登錄的密碼是謎題的缺失鍵。如果有人能夠以某種方式將數據從您的表中取出,他們將需要大量工作來破解用戶的帳戶。

所以現在回答你的問題,實際:)

就像你與你的存儲過程,當用戶匹配成功返回一個值,如1。我建議你保持你的返回碼和用戶ID值單獨使用,因此代碼中的歧義性較小。您可以選擇使用SP,您可以將返回的代碼返回到Select語句中,例如Select 1, @UserId或者您可以使用OUTPUT參數,這裏是一個相當不錯的示例:Using stored procedure output parameters in C#(我贊成後者)。

現在與你已經有了(和我的意思是,不是告訴你走開的使用System.IdentityModel.ServiceUserPrinciple和喜歡)...

一旦成功登錄已被確認工作你的SP,使用一個會話變量通過以下方式,會話變量保存服務器端所以,除非您的服務器被攻破,你會沒事:

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

現在像主頁。aspx你只需要一些代碼;

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"); 
} 

雖然這將是一個很大明智的App_Code文件夾來處理這個創建一個類,你想最後一件事是重複的代碼在你的網站。

您遇到的問題是賦予用戶權限。我不清楚你的問題,但我得到了你想要一個二進制登錄的印象,即:如果用戶通過身份驗證,他們有權訪問,簡單明瞭。如果你在分割安全之後;控制了每個用戶可以或不可以做,那麼你需要看下來基於聲明的安全的路線,這裏有這樣一個例子,讓你想:http://www.codeproject.com/Articles/2905/Role-based-Security-with-Forms-Authentication

我希望幫助並不會等太久閱讀:)

+0

感謝您的解釋,將遵循.. – moe 2015-02-01 05:22:37