membership 應用身份驗證措施

20.2  應用身份驗證措施
ASP.NET提供了許多不同類型的身份驗證措施供應用程序使用,包括基本身份驗證、摘要身份驗證、窗體身份驗證、Passport身份驗證和集成的Windows驗證。還可以開發自己的驗證方法。如果沒有給資源請求應用驗證過程,千萬不要授予對資源的訪問權限。
不同的身份驗證模式是通過設置來建立的,而這些設置可以在應用程序的web.config文件中應用,或與應用程序服務器的Internet信息服務(Internet Information Services,IIS)實例一起使用。
ASP.NET通過應用程序服務器上的一系列.config文件來配置。它們是基於XML的文件,可以很容易地改變ASP.NET的操作方式。這是操作所需配置設置的理想方式。ASP.NET配置文件以層次結構的方式來應用。.NET Framework提供了一個服務器級別的配置文件machine.config,它位於C:/Windows/Microsoft .NET/Framework/v2.0xxxxx/CONFIG。該文件夾包含machine.config和machine.config.comments文件。這些文件提供了服務器級別的ASP.NET應用程序設置,也就是說,這些設置應用於服務器上的每個ASP.NET應用程序。
web.config文件是另一個基於XML的配置文件,它位於Web應用程序的根目錄下。web.config文件中的設置會重寫上一級machine.config文件中的設置。
甚至還可以嵌套web.config文件,這樣,主應用程序的web.config文件位於應用程序的根目錄下,而其他web.config文件位於應用程序的子目錄下,如圖20-1所示。子目錄中的web.config文件會重寫根目錄下的web.config文件。所以,子目錄下的web.config文件中的設置會改變應用程序的主web.config文件中的設置。
圖  20-1
在本章的許多例子中,都使用web.config文件在應用程序中應用需要的身份驗證和授權機制。還可以使用IIS直接把這些設置應用於應用程序。
IIS是處理所有入站HTTP請求的Web服務器。必須修改IIS才能執行希望的操作。只有當頁面有特定的文件擴展名(例如.aspx),IIS才把請求發送給ASP.NET引擎。本章後面將學習如何使用IIS 5.0 和6.0。
20.2.1  <authentication>節點
在應用程序的web.config文件中使用<authentication>節點,可以設置ASP.NET應用程序需要的身份驗證類型:
<system.web>
   <authentication mode="Windows|Forms|Passport|None">
   </authentication>
</system.web>
<authentication>節點用mode屬性設置要使用的身份驗證模式。其選項包括Windows、Forms、Passport和None。表20-1解釋了這些選項。
表  20-1
提 供 程 序
說    明
Windows
Windows身份驗證與IIS身份驗證一起使用。IIS以如下方式進行驗證:basic、digest或Integrated Windows Authentication。IIS驗證完成後,ASP.NET就使用已驗證的身份授予訪問權限。這是默認設置 
Forms
未通過驗證的請求使用HTTP客戶端重定向功能重定向到一個HTML窗體上。用戶要提供登錄信息,並提交該窗體。如果應用程序驗證該請求,系統就發送一個窗體,該窗體包含重新獲得身份的憑證或密鑰
Passport
這是Microsoft 提供的一個集中式身份驗證服務,它爲成員站點提供了一個登錄和核心配置服務。Microsoft從2004年末開始不再強調這種驗證模式
None
不使用任何身份驗證模式
我們可以使用兩種方式爲ASP.NET應用程序建立身份驗證和授權模型。首先介紹Windows身份驗證模式。
20.2.2  基於Windows的身份驗證
基於Windows的身份驗證在ASP.NET應用程序所在的Windows服務器和客戶機之間處理。在基於Windows的身份驗證模型中,請求直接發送給IIS,進行驗證過程。這種類型的身份驗證在內聯網環境中非常有用。在該環境下,可以讓服務器處理這個驗證過程,尤其是用戶已登錄到網絡上時,只需獲取並利用已有的憑證完成驗證過程。
IIS首先從域登錄中獲得用戶的憑證。如果這個過程失敗,IIS就顯示一個彈出對話框,用戶可以在其中輸入或重新輸入登錄信息。要讓ASP.NET應用程序使用基於Windows的身份驗證,首先要創建一些用戶和組。
1. 創建用戶
使用基於Windows的身份驗證可以讓已提供域登錄的特定用戶訪問應用程序或其中的一部分。由於使用這種類型的驗證模式,所以ASP.NET很容易處理在內聯網環境下部署的應用程序。如果用戶在本地計算機上登錄爲一個域用戶,在訪問該域中的網絡計算機時,就不需要再次驗證。
下面的步驟說明了如何創建用戶。注意,必須有足夠的權限才能在服務器上創建用戶。如果被授予了該權限,創建用戶的步驟就如下所示:
(1) 在Windows XP或Windows Server 2003服務器上,選擇Start | Control Panel | Administrative Tools | Computer Management,打開Computer Management實用程序。它管理和控制本地Web服務器上的資源。可以使用這個實用程序完成許多任務。但這裏主要考慮用戶的創建。
(2) 展開System Tools節點。
(3) 展開Local Users and Groups節點。
(4) 選擇Users文件夾,結果如圖20-2所示。
圖  20-2
(5) 右擊Users文件夾,選擇New User,打開New User對話框,如圖20-3所示。
圖  20-3
(6) 給用戶指定名稱、密碼和描述(說明這是一個測試用戶)。這個例子把用戶命名爲Bubbles。
(7) 取消需要用戶在下次登錄時修改密碼的複選框的選中狀態。
(8) 單擊Create按鈕,就創建了測試用戶,它會顯示在Computer Management實用程序的Users文件夾中,如圖20-4所示。
圖  20-4
下面創建一個頁面,來使用這個用戶。
2. 用戶的身份驗證和授權
現在創建一個應用程序,讓用戶可以進入該應用程序。我們使用應用程序的web.config文件來控制哪些用戶允許訪問站點,哪些用戶不允許訪問站點。
把程序清單20-1中的代碼添加到web.config文件中。
程序清單20-1  通過web.config文件拒絕所有用戶
<system.web>
   <authentication mode="Windows" />
   <authorization>
      <deny users="*" />
   </authorization>
</system.web>
在這個例子中,web.config文件通過<authentication>元素的mode屬性,把應用程序配置爲使用基於Windows的身份驗證。另外,<authorization>元素還用於定義允許訪問應用程序的用戶或組的特定信息。在本例中,<deny>元素指定拒絕所有用戶(即使他們已通過身份驗證,也拒絕)訪問應用程序。使用<allow>元素可允許特定用戶訪問,但這個例子只演示<deny>的用法。結果如圖20-5所示。
試圖訪問站點的任何終端用戶,無論是已驗證的還是未驗證的,都會在瀏覽器窗口中看到Access is denied語句。我們正是希望所有的用戶都不能訪問應用程序!
圖  20-5
但在大多數情況下,我們都希望允許至少一部分用戶訪問應用程序。在web.config文件中使用<allow>元素就可以允許某個用戶訪問。下面是其語法:
<allow users="Domain/Username" />
程序清單20-2演示瞭如何允許用戶訪問應用程序。
程序清單20-2  通過web.config文件允許單個用戶訪問應用程序
<system.web>
   <authentication mode="Windows" />
   <authorization>
      <allow users="REUTERS-EVJEN/Bubbles" />
      <deny users="*" />
   </authorization>
</system.web>
即使使用<deny>元素拒絕所有用戶(甚至是已驗證的用戶)訪問,<allow>元素中定義的內容也是優先的。在這個例子中,只允許一個用戶Bubbles訪問應用程序。
現在,如果在客戶機上登錄爲Bubbles用戶,在瀏覽器中運行頁面,就可以訪問應用程序。
3. <allow>和<deny>節點詳解
<allow>和<deny>節點不僅可以操作特定的用戶,還可以操作組。這兩個元素支持表20-2中的屬性。
表  20-2
屬    性
說    明
Users
允許通過域和/或名稱指定用戶
Roles
允許指定允許或拒絕訪問的訪問組
Verbs
允許指定允許或拒絕訪問的HTTP傳輸方法
在使用這些屬性時,可以用星號(*)指定所有的用戶:
<allow roles="*" />
在這個例子中,允許所有的用戶訪問應用程序。這些屬性可以使用的另一個符號是問號(?),它表示所有的匿名用戶。例如,如果阻止所有的匿名用戶訪問應用程序,可使用下面的代碼:
<deny users="?" />
在<allow>或<deny>元素中使用users、roles或verbs屬性時,可以指定多個項,這些值用逗號隔開。如果允許多個用戶訪問,可以把這些用戶放在不同的元素中,如下所示:
<allow users="MyDomain/User1" />
<allow users="MyDomain/User2" />
也可以使用下面的代碼:
<allow users="MyDomain/User1, MyDomain/User2" />
在定義多個角色和動詞時,語法與上相同。
4. 組的身份驗證和授權
可以允許或拒絕組對應用程序或應用程序資源的訪問。服務器可以包含許多不同的組,每個組都可以有任意多個用戶。一個用戶還可以屬於多個組。打開Computer Management實用程序(Start | Control Panel | Administrative Tools | Computer Management),訪問在服務器上定義的組列表。單擊Computer Management實用程序中的Groups文件夾,就會顯示組的列表,如圖20-6所示。
圖  20-6
右擊Groups文件夾,選擇New Group,打開New Group對話框,如圖20-7所示。
圖  20-7
要創建一個組,應指定它的名稱和描述;然後單擊Add按鈕,選擇要成爲該組中成員的用戶。創建組後,就可以允許它訪問應用程序,如下所示:
<allow roles="MyGroup" />
可以使用<allow>或<deny>元素中的roles屬性,來操作剛纔創建的組或已有的組。
5. 驗證和授權HTTP傳輸方法
除了身份驗證和授權特定的用戶或用戶組之外,還可以通過特定的HTTP傳輸協議來接受或拒絕請求。這可以使用allow>或<deny>元素中的verb屬性實現:
<deny verbs="GET, DEBUG" />
在這個例子中,使用HTTP GET或HTTP DEBUG協議傳輸的請求會被拒絕訪問站點。verbs屬性的值可以是POST、GET、HEAD和DEBUG。
6. 集成的Windows身份驗證
前面使用默認的集成Windows身份驗證模式進行驗證和授權。如果處理的是內聯網應用程序,且每個客戶機都使用Windows,就沒什麼問題。Windows是支持該驗證模式的唯一系統。這個身份驗證系統還要求客戶機使用Microsoft的Internet Explorer,但實際情況並非總是如此。
集成的Windows身份驗證以前稱爲NTLM或Windows NT Challenge/Response身份驗證。這個驗證模式要求客戶機給駐留ASP.NET應用程序的服務器發送其憑證的散列,以此證明其身份。除了Microsoft的Active Directory之外,如果客戶機使用的是Microsoft的Internet Explorer 5或更高版本,還可以使用Kerberos。
7. 基本身份驗證
另一個選項是使用基本身份驗證,它也要求客戶機提供用戶名和密碼,以驗證其身份。基本身份驗證的一大優點是,它是HTTP規範的一部分,所以大多數瀏覽器都支持它。基本身份驗證的缺點是,它把用戶名和密碼作爲明文傳送給服務器,所以用戶名和密碼很容易被竊取。因此,基本身份驗證必須與SSL(安全套接字層)一起使用。
爲了給應用程序應用基本身份驗證,必須打開IIS,再打開Web站點的Properties對話框。選擇Directory Security選項卡,單擊Anonymous Access and Authentication Control框中的Edit按鈕。打開Authentication Methods對話框。
取消對底部Integrated Windows authentication複選框的選擇,再選中它上面的Basic authentication複選框,如圖20-8所示。此時會顯示一個警告,說明這個方法把用戶名和密碼作爲明文傳送。
圖  20-8
最後單擊對話框中的OK按鈕。現在應用程序使用基本身份驗證模式,而不是集中式Windows身份驗證模式。
8. 摘要身份驗證
摘要身份驗證(digest authentication)是本節介紹的最後一種模式。該模型解決了基本身份驗證把客戶機的憑證作爲明文傳送的問題。摘要身份驗證在把客戶機的憑證傳送給應用程序服務器之前,使用一個算法加密了它們。
要使用摘要身份驗證,需要有一個Windows域控制器。摘要身份驗證的一個主要問題是,不是所有的平臺都支持它,瀏覽器必須遵循HTTP 1.1規範。但摘要身份驗證不僅可與防火牆一起工作,還與代理服務器兼容。
在Authentication Methods對話框中選中Digest authentication複選框,就爲應用程序選擇了摘要身份驗證。
20.2.3  基於窗體的身份驗證
基於窗體的身份驗證是允許用戶訪問整個應用程序或其特定資源的一種流行模式。使用它可以把登錄窗體直接放在應用程序中,這樣,終端用戶只需把用戶名和密碼輸入到瀏覽器中的一個HTML窗體上即可。基於窗體的身份驗證的一個缺點是:用戶名和密碼作爲明文傳送,除非使用了SSL。
很容易在Web應用程序中實現基於窗體的身份驗證。首先修改應用程序的web.config文件,如程序清單20-3所示。
程序清單20-3  爲基於窗體的身份驗證修改web.config文件
<system.web>
   <authentication mode="Forms">
      <forms name="Wrox" loginUrl="Login.aspx" path="/" />
   </authentication>
   <authorization>
      <deny users="?" />
   </authorization>
</system.web>
這個結構必須應用於web.config文件。首先使用前面介紹的<authorization>元素,可以拒絕所有匿名用戶訪問應用程序。只有驗證用戶才能訪問應用程序包含的頁面。
如果請求者未通過驗證,就執行<authentication>元素中定義的內容。mode屬性的值設置爲Forms,爲Web應用程序使用基於窗體的身份驗證。下一個指定的屬性是loginUrl,它指向包含應用程序的登錄窗體的頁面。在這個例子中,該頁面指定爲Login.aspx。如果試圖訪問應用程序的終端用戶未通過身份驗證,他的請求就會被重定向到Login.aspx,以便對該用戶進行驗證和授權。在提供了有效的憑證後,用戶就會返回到他在應用程序中最初發出請求的地方。這裏使用的最後一個屬性是path,它指定了保存cookie的位置。該cookie用於保存授權用戶的訪問令牌。在大多數情況下,該值默認爲/。表20-3列出了<forms>元素的屬性。
表  20-3
屬    性
說    明
name
這是賦予cookie的名稱,該cookie用於在請求之間保存用戶。其默認值是.ASPXAUTH 
loginUrl
如果沒有找到有效的驗證cookie,就指定將請求重定向到的URL。其默認值是Login.aspx
(續表)   
屬    性
說    明
protection
指定要應用於驗證cookie的保護級別。它有4個設置:
• All: 應用程序使用數據有效性驗證和加密機制來保護cookie。這是默 認設置。
• None: 不加密cookie。
• Encryption: 加密cookie,但不對它進行數據有效性驗證。以這種方   式 使用的cookie可能會受到純文本攻擊。
• Validation: 與Encryption設置相反,進行數據有效性驗證,但不加密cookie 
path
指定應用程序所用cookie的路徑。在大多數情況下應使用/,它是默認設置
timeout
指定cookie過期後的時間(分鐘),其默認值是30
cookieless
指定在進行驗證和授權過程中,基於窗體的身份驗證過程是否使用cookie
defaultUrl
指定默認的URL
domain
指定要與窗體身份驗證cookie一起發送的域名
slidingExpiration
指定是否給cookie應用可變的過期時間。如果該屬性設置爲True,就對發送給服務器的每個請求重新設置cookie的過期時間。其默認值是False 
enableCrossAppsRedirect
指定是否允許跨應用程序的重定向
requireSSL
指定在傳輸身份驗證信息時是否需要SSL連接
有了web.config文件後,就給應用程序創建一個可以訪問的頁面。程序清單20-4顯示了一個簡單的頁面。
程序清單20-4  一個簡單的頁面Default.aspx
<%@ Page Language="VB" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>The Application</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
       Hello World
    </div>
    </form>
</body>
</html>
這個頁面在瀏覽器上寫入了Hello World。窗體身份驗證的強大功能在程序清單20-5的Login.aspx頁面中有所體現。
程序清單20-5  Login.aspx頁面
VB
<%@ Page Language="VB" %>
<script runat="server">
    Protected Sub Button1_Click(ByVal sender As Object, _
      ByVal e As System.EventArgs)
        If (TextBox1.Text = "BillEvjen" And TextBox2.Text = "Bubbles") Then
            FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, True)
        Else
            Response.Write("Invalid credentials")
        End If
    End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Login Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        Username<br />
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br />
        <br />
        Password<br />
        <asp:TextBox ID="TextBox2" runat="server" 
         TextMode="Password"></asp:TextBox><br />
        <br />
        <asp:Button ID="Button1" OnClick="Button1_Click" runat="server" 
         Text="Submit" />
    </div>
    </form>
</body>
</html>
C#
<%@ Page Language="C#"%>
<script runat="server">
   protected void Button1_Click(object sender, EventArgs e)
    {
        if (TextBox1.Text == "BillEvjen" && TextBox2.Text == "Bubbles") {
            FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, true);
        }
        else {
            Response.Write("Invalid credentials"); 
        }
    }
</script>
Login.aspx有兩個簡單的TextBox控件和一個按鈕控件,該按鈕控件要求用戶提交用戶名和密碼。Button1_Click事件使用FormsAuthentication類的RedirectFromLoginPage方法。這個方法把請求從Login.aspx重定向到最初請求的資源。
RedirectFromLoginPage方法有兩個參數。第一個參數是用戶名,用於進行cookie驗證。這個參數並不映射爲賬戶名,而是由ASP.NET的URL授權功能使用。第二個參數指定是否生成一個永久的cookie。如果它設置爲True,終端用戶從一個瀏覽器會話到下一個會話時,就不需要再次登錄。
使用前面構建的3個頁面,程序清單20-4中對Default.aspx頁面的每個請求都會導致ASP.NET檢查是否存在正確的身份驗證令牌。如果沒有找到該令牌,請求就重定向到指定的登錄頁面(本例是Login.aspx)。查看瀏覽器中的URL會發現,ASP.NET使用一個查詢字符串值,以確定用戶獲得授權後把用戶返回到什麼地方。
http://localhost:35089/Security/Login.aspx?ReturnUrl=%2fSecurity%2fDefault.aspx
其中的查詢字符串ReturnUrl使用了最初請求的頁面和文件夾的值。
查看程序清單20-5中的Login.aspx頁面,注意要檢查兩個文本框中的值,確保它們遵循特定的用戶名和密碼。如果用戶名和密碼正確,就調用RedirectFromLoginPage方法,否則就使用Response.Write語句。在大多數情況下,都不要在代碼中對用戶名和密碼硬編碼。還有許多其他選項用於檢查用戶名和密碼是否來自授權用戶,下面介紹其中一些選項。
1. 根據web.config文件包含的值進行驗證
上一個例子不是處理爲驗證提供的用戶名和密碼的最佳方式。把這些信息直接硬編碼到應用程序並不好。下面把這些值存儲在web.config文件中。
在程序清單20-3中,web.config文件的<forms>元素還可以有子元素。子元素<credentials>允許直接在web.config文件中指定用戶名和密碼組合。可以用兩種方式添加這些值。最簡單的方法如程序清單20-6所示。
程序清單20-6  修改web.config文件,添加用戶名和密碼值
<system.web>
   <authentication mode="Forms">
      <forms name="Wrox" loginUrl="Login.aspx" path="/">
         <credentials passwordFormat="Clear">
            <user name="BillEvjen" password="Bubbles" />
         </credentials>
      </forms>
   </authentication>
   <authorization>
      <deny users="?" />
   </authorization>
</system.web>
<credentials>元素在配置文件中添加了用戶及其密碼。<credentials>有一個屬性passwordFormat,其值可以是Clear、MD5和SHA1。下面描述了這些選項:
●       Clear:密碼存儲爲明文。用戶的密碼直接與這個值比較,不需要進一步轉換。
●       MD5:密碼使用消息摘要5(Message Digest 5,MD5)散列摘要進行存儲。在驗證憑證時,用戶密碼使用MD5算法進行散列,再與這個值進行相等比較。不會存儲或比較明文密碼。這個算法比SHA1的性能好。
●       SHA1:密碼使用SHA1散列摘要來存儲。在驗證憑證時,用戶密碼使用SHA1算法進行散列,再與這個值進行相等比較。不會存儲或比較明文密碼。這個算法的安全性最高。
在程序清單20-6的例子中,使用了Clear設置。這不是最安全的方法,但可用於演示。<credentials>的一個子元素是<user>,在該子元素中,可以使用屬性name和password爲授權用戶定義用戶名和密碼。
接着修改Login.aspx頁面上的Button1_Click事件,如程序清單20-7所示。
程序清單20-7  修改Login.aspx頁面以使用web.config文件
VB
<%@ Page Language="VB" %>
<script runat="server">
    Protected Sub Button1_Click(ByVal sender As Object, _
      ByVal e As System.EventArgs)
        If FormsAuthentication.Authenticate(TextBox1.Text, TextBox2.Text) Then
            FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, True)
        Else
            Response.Write("Invalid credentials")
        End If
    End Sub
</script>
C#
<%@ Page Language="C#"%>
<script runat="server">
    protected void Button1_Click(object sender, EventArgs e)
    {
        if (FormsAuthentication.Authenticate(TextBox1.Text, TextBox2.Text)) {
            FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, true);
        }
        else {
            Response.Write("Invalid credentials"); 
        }
    }
</script>
在這個例子中,使用Authenticate方法,讓ASP.NET頁面查找存儲在web.config文件中的憑證,以進行驗證。Authenticate方法帶有兩個參數:要檢查的用戶名和密碼。如果找到了憑證,就調用RedirectFromLoginPage方法。
最好不要像上面的例子那樣,在web.config文件中把用戶的密碼存儲爲明文,而應使用散列功能,防止終端用戶的密碼被竊取。爲此,應在配置文件中保存散列的密碼,如程序清單20-8所示。
程序清單20-8  使用加密的密碼
<forms name="Wrox" loginUrl="Login.aspx" path="/">
   <credentials passwordFormat="SHA1">
      <user name="BillEvjen" password="58356FB4CAC0B801F011B397F9DFF45ADB863892" />
   </credentials>
</forms>
使用這種構建方式,甚至開發人員都不知道密碼,因爲沒有使用明文密碼。Login.aspx頁面中的Authenticate方法使用SHA1對密碼進行散列(因爲這是web.config的<credentials>節點指定的方法),對這兩個散列進行比較。如果它們匹配,就給用戶授權。
在使用SHA1或MD5時,唯一要修改的是web.config文件。不必修改登錄頁面或應用程序的其他頁面。但要存儲散列的密碼,應使用FormsAuthentication.HashPasswordFor StoringInConfigFile方法(它是.NET Framework中最長的方法名),以如下方式進行:
FormsAuthentication.HashPasswordForStoringInConfigFile(TextBox2.Text, "SHA1")
2. 根據數據庫中的值進行驗證
獲取用戶名和密碼的另一個常用方式是直接從數據庫中獲取。這樣可以根據存儲在Microsoft SQL Server中的值檢查用戶輸入的憑證。其代碼如程序清單20-9所示。
程序清單20-9  在SQL Server中檢查憑證(Login.aspx)
VB
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
    Protected Sub Button1_Click(ByVal sender As Object, _
      ByVal e As System.EventArgs)
       Dim conn As SqlConnection
       Dim cmd As SqlCommand
       Dim cmdString As String = "SELECT [Password] FROM [AccessTable] WHERE" & _
          " (([Username] = @Username) AND ([Password] = @Password))"
        
       conn = New SqlConnection("Data Source=localhost;Initial " & _
          "Catalog=Northwind;Persist Security Info=True;User ID=sa")
       cmd = New SqlCommand(cmdString, conn)
        
       cmd.Parameters.Add("@Username", SqlDbType.VarChar, 50)
       cmd.Parameters("@Username").Value = TextBox1.Text
       cmd.Parameters.Add("@Password", SqlDbType.VarChar, 50)
       cmd.Parameters("@Password").Value = TextBox2.Text
        
       conn.Open()
        
       Dim myReader As SqlDataReader
        
       myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
        
       If myReader.Read() Then
          FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, False)
       Else
          Response.Write("Invalid credentials")
       End If
        
       myReader.Close()    
   End Sub
</script>
C#
<%@ Page Language="C#"%>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
    protected void Button1_Click(object sender, EventArgs e)
    {
       SqlConnection conn;
       SqlCommand cmd;
       string cmdString = "SELECT [Password] FROM [AccessTable] WHERE" +
          " (([Username] = @Username) AND ([Password] = @Password))";
        
       conn = new SqlConnection("Data Source=localhost;Initial " +
          "Catalog=Northwind;Persist Security Info=True;User ID=sa");
       cmd = new SqlCommand(cmdString, conn);
        
       cmd.Parameters.Add("@Username", SqlDbType.VarChar, 50);
       cmd.Parameters["@Username"].Value = TextBox1.Text;
       cmd.Parameters.Add("@Password", SqlDbType.VarChar, 50);
       cmd.Parameters["@Password"].Value = TextBox2.Text;
        
       conn.Open();
        
       SqlDataReader myReader;
        
       myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        
       if (myReader.Read()) {
          FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, false);
       }
       else {
          Response.Write("Invalid credentials");
       }
        
       myReader.Close(); 
    }
</script>
除了Login.aspx頁面之外,其他都與前面的例子相同。現在可以根據存儲在SQL Server中的數據驗證用戶名和密碼。在Button1_Click事件中,建立了與SQL Server的連接(爲了安全起見,應把連接字符串存儲在web.config文件中)。傳送參數TextBox1和TextBox2中的輸入。如果返回了結果,就調用RedirectFromLoginPage方法。
3. 聯合使用Login控件和窗體身份驗證
前面介紹瞭如何聯合使用ASP.NET窗體身份驗證和標準的ASP.NET服務器控件,例如簡單的文本框和按鈕控件。也可以在定製開發的窗體身份驗證架構中使用ASP.NET 2.0最新版本的服務器控件,例如新的Login服務器控件。這說明ASP.NET非常強大—— 可以組合許多不同的部分,構建出希望的解決方案。
程序清單20-10顯示了一個使用新Login服務器控件修改的Login.aspx頁面。
程序清單20-10  在Login.aspx頁面上使用Login服務器控件
VB
<%@ Page Language="VB" %>
<script runat="server">
    Protected Sub Login1_Authenticate(ByVal sender As Object, _
      ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs)
        If (Login1.UserName = "BillEvjen" And Login1.Password = "Bubbles") Then
            FormsAuthentication.RedirectFromLoginPage(Login1.UserName, _
               Login1.RememberMeSet)
        Else
            Response.Write("Invalid credentials")
        End If
    End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Login Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Login ID="Login1" runat="server" OnAuthenticate="Login1_Authenticate">
        </asp:Login>
    </div>
    </form>
</body>
</html>
C#
<%@ Page Language="C#" %>
<script runat="server">
    protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
    {
        if (Login1.UserName == "BillEvjen" && Login1.Password == "Bubbles") {
            FormsAuthentication.RedirectFromLoginPage(Login1.UserName,
               Login1.RememberMeSet);
        }
        else {
            Response.Write("Invalid credentials");
        }
    }
</script>
頁面上沒有Button服務器控件,所以使用Login控件的OnAuthenticate屬性指向身份驗證服務器端事件Login1_Authenticate。該事件查找授權信息(但本例中將其值硬編碼了)。Login控件的用戶名文本框可以通過Login1.UserName聲明訪問,密碼可以使用Login1.Password訪問。Login1.RememberMeSet屬性用於指定是否存儲用戶的驗證cookie,這樣在下次訪問時用戶就不必驗證身份了。
這個例子比使用文本框和按鈕控件創建自己的登錄窗體簡單得多。可以給Login控件提供預定義的外觀和操作方式,也可以使用Login控件的子控件屬性。總之,在ASP.NET應用程序中使用什麼方法取決於我們自己。
4. FormsAuthentication類
從本章的窗體身份驗證一節的各例子可以看出,許多任務的實現都取決於FormsAuthentication類。所以,下面看看這個類。
FormsAuthentication類有許多方法和屬性,可以讀取和控制驗證cookie以及其他信息(例如請求的返回URL)。表20-4列出了FormsAuthentication類的一些方法和屬性。
表  20-4
方法/屬性
說    明
Authenticate
這個方法用於驗證存儲在配置文件(例如web.config)中的憑證
Decrypt
返回一個有效的加密驗證票據實例,該實例從HTTP cookie中提取,是FormsAuthenticationTicket類的一個實例
Encrypt
創建一個字符串,其中包含一個有效的加密驗證票據實例,該實例可用於HTTP cookie
FormsCookieName
給當前應用程序返回cookie的名稱 
FormsCookiePath
給當前應用程序返回cookie的路徑(cookie的位置)
GetAuthCookie
給指定的用戶提供一個驗證cookie
GetRedirectUrl
返回一個URL,用戶通過登錄頁面授權後,就會重定向到這個URL上
HashPasswordFor Storing InConfigFile
創建所提供的字符串密碼的散列。這個方法帶兩個參數,一個是密碼,另一個是要在字符串上實現的散列類型。散列值可以是SHA1 和MD5
Initialize
通過從web.config文件中讀取配置設置,以及獲取應用程序的給定實例中使用的cookie和加密鍵,來執行FormsAuthentication類的初始化
RedirectFromLogin Page
把HTTP請求重定向回最初請求的頁面。只能在用戶獲得授權後執行這個操作
RenewTicketIfOld
在FormsAuthenticationTicket實例上有條件地更新可變的過期時間
RequireSSL
指定cookie是否應只通過SSL(HTTPS)傳輸
SetAuthCookie
創建一個驗證票據,把它關聯到輸出響應包含的cookie
SignOut
刪除驗證票據
SlidingExpiration
提供一個布爾值,表示過期時間是否可變
20.2.4  Passport身份驗證
驗證終端用戶的另一種方法是使用Microsoft的Passport標識系統。有Passport賬戶的用戶可以有一個簽名解決方案,也就是說,他只需這些憑證就可以登錄到Internet的站點和其他支持Passport的站點和應用程序上。
應用程序支持Passport身份驗證時,請求會被重定向到Microsoft Passport站點上,在該站點上,用戶可以輸入憑證。如果驗證成功,用戶就可以獲得授權,請求被重定向迴應用程序。
很少有Internet站點和應用程序使用Microsoft的Passport技術。實際上,Microsoft在2005年完全拋棄了Passport,大多數對全局身份驗證和授權標準感興趣的公司都轉而使用Project Liberty作爲其解決方案(www.projectliberty.org)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章