2012-01-10 98 views
18

由於關於此過程的文檔非常含糊且令人困惑(或舊),因此我想驗證我是否正確地執行了操作並且沒有錯過任何步驟。Forms身份驗證理解context.user.identity

我想創建一個安全的登錄系統,在瀏覽器關閉時過期。

- 在我的web.config我有以下 -

<authentication mode="Forms"> 
     <forms loginUrl="~/Login.aspx" defaultUrl="Index.aspx" name=".ASPXFORMSAUTH" timeout="100" /> 
    </authentication> 
    <authorization> 
     <allow users="?" /> 
    </authorization> 
    <machineKey decryption="AES" validation="SHA1" validationKey.......... /> 

所以我有一個用戶名/密碼文本框登錄表單,這個按鈕:

<asp:Button ID="LoginButton" runat="Server" OnClick="Login_Authenticate" Text="Sign in" /> 

裏面Login_Authenticate我做如下:

protected void Login_Authenticate(object sender, EventArgs e){ 
string userName = UserName.Text; 
string password = Password.Text; 

bool Authenticated = false; 

// Here's code that makes sure that Username and Password is CORRECT 
if(AuthClass.Authenticate(userName, password)){ 
Authenticated = true; 
} 
// error checking does happen here. 

if (Authenticated) 
{ 
    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(30), rememberUserName, String.Empty, FormsAuthentication.FormsCookiePath); 
    string encryptedCookie = FormsAuthentication.Encrypt(ticket); 
    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie); 
    cookie.Expires = DateTime.Now.AddMinutes(30); 
    Response.Cookies.Add(cookie); 
    //FormsAuthentication.RedirectFromLoginPage(userName, false); 

    Response.Redirect("MainPage.aspx"); 
} 
} 

---在MasterPage.master.cs中我有以下檢查Page_Init( )---

if (Context.User.Identity.IsAuthenticated) 
    { 
     int userid = (int)Session["userid"]; 
     if (userid == null) 
     { 
     userid = GetUserID(Context.User.Identity.Name); 
     if (userid != null) 
     { 
      Session["userid"] = userid; 
     } 
     } 
    } 

編輯: --- Global.asax中;一些代碼,我不太清楚是正確的或不知道它做什麼

protected void Application_AuthenticateRequest(object sender, EventArgs e) 
    { 
     // look if any security information exists for this request 
     if (HttpContext.Current.User != null) 
     { 
      // see if this user is authenticated, any authenticated cookie (ticket) exists for this user 
      if (HttpContext.Current.User.Identity.IsAuthenticated) 
      { 
       // see if the authentication is done using FormsAuthentication 
       if (HttpContext.Current.User.Identity is FormsIdentity) 
       { 
        // Get the roles stored for this request from the ticket 
        // get the identity of the user 
        FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity; 
        //Get the form authentication ticket of the user 
        FormsAuthenticationTicket ticket = identity.Ticket; 
        //Get the roles stored as UserData into ticket 
        string[] roles = { }; 
        //Create general prrincipal and assign it to current request 

        HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(identity, roles); 
       } 
      } 
     } 
    } 

---從那時起,每一頁上,我使用會話用戶ID來收集用戶信息和內容,並確保用戶具有適當的身份驗證和組角色權限。

這一切是否正確?或者我必須在任何地方解密任何東西?

這足以讓一個安全的用戶登錄?還是應該不打擾表單身份驗證,並找到我自己的方式來製作自己的cookie並自行管理它?

+0

如果什麼代碼失敗總是驗證方返回布爾認證=假真; //這是確保用戶名和密碼是CORRECT Authenticated = true的代碼;這是你在頂部..但如果代碼失敗它從來沒有設置認證回false。 – MethodMan 2012-01-10 21:11:51

+0

@DJKRAZE代碼確實將其設置爲false,如果有錯誤。我只是沒有包含檢查用戶名/密碼的冗長代碼。 Authenticated = true只有在一切成功時纔會發生。 – Dexter 2012-01-10 21:13:58

+0

增加了一些更多的澄清代碼,包括我使用的Global.asax代碼。我不知道它是否工作,我很困惑。 – Dexter 2012-01-10 21:25:03

回答

12

您的代碼寫入方式登錄將持續瀏覽器會話。這可能有助於瞭解正在發生的事情的基礎知識。

對於基於cookie的身份驗證方法,實際上有三個動作:

1)登錄 - 驗證用戶的憑據,並創建和存儲在他們的瀏覽器的cookie。

2)註銷 - 只需將刪除瀏覽器中的cookie(由過期的餅乾或刪除它)

3)每請求驗證(也就是部分是你的Application_AuthenticateRequest) - 檢查,看是否有cookie存在,如果是,獲取用戶的標識和角色並設置HttpContext.Current.User。

通常情況下,FormsAuthentication模塊將大部分隱藏起來。它看起來像你的代碼正在嘗試使用FormAuthentication的一些元素(如FormsAuthenticationTicket和FormsIdentity。只要你得到你想要的,這是很好的

你的Login_Authenticate方法看起來很好除了你設置過期即使你關閉並重新打開瀏覽器,這也會使cookie保持不變,因爲這不是你想要的行爲,所以我不會設置cookie過期時間,這個設置就像檢查「記住我」複選框一樣。

Application_AuthenticateRequest中的代碼每次從應用程序提供頁面時都會運行,它的主要工作是設置HttpContext.Current.User。通常,如果沒有用戶登錄,則User是null或Anonymous用戶。已登錄,這應該代表你的用戶。

如果你正在做這三件事,那麼你的代碼中的任何地方都可以引用HttpContext.Current.User來決定你想要顯示的信息級別。例如,如果您只想將頁面限制爲僅限管理員,則可以調用HttpContext.Current.Users.IsInRole(「Administrators」),如果調用返回false,則將它們從頁面重定向。

希望這會有所幫助。

+0

我明白了。我與我自己是否要使用cookies並堅持 - 或者是否在瀏覽器關閉時結束會話。我仍然無法決定是否應該去安全或方便。 --- Application_AuthenticateRequest中的代碼是否也適用於一切?我不需要解密或者我的代碼中的任何地方的cookie?你是什​​麼意思的FormsAuthentication隱藏,它究竟隱藏什麼,爲什麼我不應該使用FormAuthentication門票?我不想在Current.Users中使用角色,因爲無論如何我都會查詢數據庫以獲取特定的角色系統。 – Dexter 2012-01-11 06:30:21

+0

由於您使用FormsCookieName設置cookie,並且啓用了FormsAuthentication,因此在調用Application_AuthenticateRequest之前,Forms Authentication將解密cookie併爲您設置HttpContext.Current.User。使用FormAuthentication門票是完全可以接受的。 – 2012-01-11 15:49:55

+0

對於最後一部分,使用角色 - 請記住,HttpContext.Current.User幾乎在您的請求處理的任何地方都可用。爲了避免爲每個「角色」查詢命中數據庫,可以使用一次數據庫調用爲Application_AuthenticateRequest中的用戶設置所有角色。考慮它是「每個請求角色緩存」。 – 2012-01-11 15:51:13

2

有沒有在您的授權標籤的問題,應該是:

<authorization> 
    <deny users="?" /> 
    <allow users="*" /> 
</authorization> 

,因爲你要拒絕匿名用戶。如果您解決了這個問題,您可以安全地從主頁面和global.asax中刪除所有內容 - 您不必將表單標識重新映射到存儲在會話中的自定義標識。這是浪費資源,我不認爲它會以重大的方式提高解決方案的安全性。你可以依靠表單cookie。

+0

啊我明白了。但我希望匿名用戶可以看到,像主頁面一樣選擇登錄。我確實希望他們看到某些其他頁面。我還需要使用MasterPage的東西,因爲我需要每個頁面上的用戶ID,我必須在MasterPage上檢查身份驗證,否則ASP.net將如何知道哪些頁面不允許匿名用戶?我必須確保用戶在很多頁面上登錄。 (if context.identity.IsAuthenticated是一個大的if/else樹的一部分,所以還有其他的情況)。 – Dexter 2012-01-11 06:36:27

+0

另外我的重定向在最後不工作... – Dexter 2012-01-11 18:14:07

+0

這是什麼意思「不工作」? – 2012-01-11 18:55:08

6

我有點晚了關於這個問題的,但對於那些試圖實現窗體身份驗證,同時保持事情簡單(像我想),這裏的有關最新文檔我已經在MSDN上找到: http://msdn.microsoft.com/en-us/library/xdt4thhy(v=vs.100).aspx

簡而言之,不要搞亂設置cookie,檢查它們,實例化門票或校長,...留給FormsAuthentication班。

在日誌上,當您的代碼檢查憑據,如果它們是有效的,只是叫

FormsAuthentication.RedirectFromLoginPage(yourUserId, false); 

它爲您設置身份驗證cookie,它與重定向相結合,就足夠了。 「false」用於不保留授權:在瀏覽器關閉時(或授權超時)它將丟失。

在已經過身份驗證的請求上,沒有任何內容需要通過代碼檢查以確保您的身份驗證有效。使用Context.User.Identity.Name知道誰連接(將是上面的字符串yourUserId)。

在明確的退出,呼籲

FormsAuthentication.SignOut(); 
FormsAuthentication.RedirectToLoginPage(); 

而且具有在web.config中配置表單認證。

<system.web> 
    <authentication mode="Forms"> 
    <forms loginUrl="yourLoginPage" defaultUrl="yourDefaultPageAfterLogin"> 
    </forms> 
    </authentication> 
    <authorization> 
    <deny users="?" /> 
    </authorization> 
</system.web> 

注意,對於MVC應用程序的授權部分應該從配置中刪除,並註冊爲全局篩選器屬性AuthorizeAttribute處理,對控制器或動作需要它的AllowAnonymousAttribute使用。 (MVC 4;在此之前,需要創建自己的屬性來處理該屬性)。

相關問題