2010-05-27 67 views
2

我使用的數據庫中包含用戶名/密碼列表以及允許用戶輸入用戶名/密碼的簡單Web表單。我的網站的身份驗證和安全 - 需要諮詢

當他們提交頁面時,我只需執行存儲過程檢查即可進行身份驗證。如果他們被授權,則他們的用戶詳細信息(例如用戶名,dob,地址,公司地址,其他重要信息)將存儲在自定義用戶對象中,然後存儲在會話中。我創建的這個自定義User對象用於整個Web應用程序,也用於子站點(會話共享)。

我的問題/問題是:

  1. 是我的身份驗證方法做事的正確方法是什麼?

  2. 我發現用戶抱怨說他們的會話已經過期,儘管他們「沒有空閒」,可能是因爲應用程序池回收?他們輸入大量文本並發現他們的會話已過期,從而失去了輸入的所有文本。我不確定會話確實是否偶爾重置,但是使用cookie/cookiless的表單身份驗證是否可以解決問題?

  3. 或者,我應該在會話,cookie或其他內容中構建和存儲用戶對象,以便更「正確」並避免像點#2這樣的情況。

  4. 如果我使用Forms Authentication路由,我認爲我無法將自定義User對象存儲在Forms Authentication cookie中,這是否意味着我將存儲UserID,然後在每個頁面上重新創建用戶對象?這不會是服務器負載的巨大增長嗎?

建議和答覆非常感謝。

大號

回答

0
  1. 它並不真正關心你是否使用自己的身份驗證系統,或使用這種簡單場景時的默認會員供應商。
  2. 當應用程序可能每天有幾次回收時,您應該避免使用會話狀態InProc。而是將您的會話存儲到數據庫(SqlSessionState)或使用StateServer。然後,應用程序池可以整天回收,而不會干擾您的會話。將會話超時設置爲60分鐘或什麼,將解決剩餘的問題。 永遠不要使用無Cookie會話(除非你知道你在做什麼),,因爲它們使得偷取會話的方式太容易
  3. 只需將其存儲到會話中(或使用默認成員資格提供程序的配置文件)。不僅cookie容易讀取,而且限制爲4 KB。
  4. 不,您將擁有存儲所有用戶信息的配置文件。使用表單身份驗證或將其數據存儲到SqlSessionState的自定義系統無關緊要。成員資格提供者會將資料ID存儲到一個cookie中,與會話狀態相同將會話ID保存到一個cookie中。
+0

非常感謝您的支持:-) 我已經設置了我的網站以將會話存儲在SQL DB中。 您是否大致瞭解使用了多少內存以及是否應該擔心? 謝謝 – Ichirichi 2010-07-28 16:12:20

0

我的建議是使用asp.net成員資格和角色(微軟)。這是一個非常好的安全解決方案 - 登錄安全性,角色(權限)並存儲在SQLServer數據庫中(不確定它是否可以存儲在別處)。

我在我的網站上使用它,您可以直接使用會員控制(登錄表單,更改密碼等),也可以自己推出。

我發現的唯一棘手的問題是在dB中設置成員表,視圖和存儲過程(你下載了一個dB腳本),但實際上這很簡單。

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

+0

感謝您的建議。問題在於我們將用戶名和密碼存儲在一個單獨的(已經存在的數據庫)中,所以我認爲這不適合我。 – Ichirichi 2010-07-28 16:34:17

1

您可以使用ASP.NET Membership, Roles, Forms Authentication, and Security Resources 我會用舉一個例子C#

僅供參考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); 
     } 
    } 
1

只要觸及第4點 - 在內存中不存儲每個人的「用戶」對象並在每個HTTP請求中重新創建對象會更有效率。通過這種方式,您還可以重新驗證登錄詳細信息 - 如果某人的帳戶遭到入侵併且實際用戶更改了密碼以嘗試保護其帳戶,但「壞用戶」已經登錄,該怎麼辦?在您的安全機制下,由於用戶數據被緩存,並且不會在每次回發中重新驗證,所以「不良用戶」可以繼續瀏覽。

1

以下是一些初級和高級Web開發人員必須遵循的一般安全措施。


 #15 Steps To Secure Your Website 

1:防止圖像盜鏈(IMP)

圖片盜鏈是使用我們的網站,別人的圖片網址,並使用他們的帶寬的過程。爲了防止這種謎團,我們可以通過在代碼中添加以下行來阻止訪問外部服務器。

RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC] 
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L] 

2:防止CSRF(跨站請求僞造)攻擊

爲了防止您的GET CSRF攻擊和POST請求的表單提交,您可以使用以下兩種方法。
首先它爲每個請求包含隨機標記,這是爲每個會話生成的唯一字符串。
第二種方法是爲每個表單字段使用隨機名稱。

3:防止目錄訪問/禁用索引

添加下面一行到你的.htaccess文件。

Options -Indexes 

4:IP限制,保護您的私人和CMS登錄

IP限制是先進而有效的方法來阻止未經授權的人員訪問您的網站的特定區域有點方式。 這是一個示例htaccess代碼,用於IP限制對特定位置的訪問。

ALLOW USER BY IP 
<Limit GET POST> 
order deny,allow 
deny from all 
allow from 1.2.3.4 
</Limit> 

5:保護你的。htaccess文件

你可以在你的htaccess文件中寫下這段代碼,它不讓任何人訪問你的htaccess文件。

<Files ~ 「^.*.([Hh][Tt][Aa])」> 
order allow,deny 
deny from all 
satisfy all 
</Files> 

6:功能訪問規則

通過添加「_」作爲函數名稱的前綴,我們可以防止功能從網絡上公開被調用。當我們只需要通過AJAX訪問某些特定功能時,這是最佳實踐。

7:鎖定你的目錄和文件權限

文件權限定義誰可以做什麼到一個文件中。
「閱讀」= 4:查看文件內容。
「寫入」= 2:更改文件內容。
「執行」= 1:運行程序文件或腳本。

8:防止cron作業從Web瀏覽器

運行通過添加,下面的代碼行中你的頁面,可以保護您的網頁從Web瀏覽器訪問。

if(! $this->input->is_cli_request()) { 
      die("Only CLI Requests Allowed"); 
} 

9:隱藏的管理頁面被谷歌

你不希望你的管理頁面被搜索引擎收錄,所以你應該使用ROBOTS_TXT文件從列出這些阻礙搜索引擎抓取。

10:禁用右鍵單擊頁面,如果不要求

禁用「右鍵」,以此來查看檢查元素,以確保爲廣大用戶提供網站內容的網站源代碼。

11:用於CMS

不斷實踐使用強密碼來設置隨機密碼,只有特殊字符。

12:請聯繫目錄很難猜測

它可能發生,黑客可以利用該掃描所有的目錄,Web服務器上像「管理員」或贈品的名稱「登錄」等腳本和顯著的東西可能會泄露。

13:更改數據庫表前綴

添加前綴這將是很難推測有擔保方(項目名稱和年份的混合物)。
爲了說明,
A)BPM最高=> bpm14_download
B)Glickin => gk15_admin
C)TravelWorthy => tw16_user

14:防止用戶的密碼,這是因爲重要的,因爲你的

關於密碼加密算法,使用sha1算法,而不是傳統算法Md5,這是一種非常古老的方式,現在每個來源都變得不太安全。
參考:http://php.net/manual/en/function.sha1.php

15:隱藏錯誤日誌

在發展方式轉變,保持錯誤報告「ALL」,一旦我們去爲「0」沒有忘記LIVE變化。在這裏
參考:http://php.net/manual/en/function.error-reporting.php