熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

ASP.NET 2.0 中的 Windows 身份驗證

2013-11-13 10:22:14  來源: .NET編程 

  概述

  身份驗證是一個驗證客戶端身份的過程通常采用指定的第三方授權方式客戶端可能是最終用戶計算機應用程序或服務客戶端的標識稱為安全原則為了使用服務器應用程序進行驗證客戶端提供某種形式的憑據來允許服務器驗證客戶端的標識確認了客戶端的標識後應用程序可以授予執行操作和訪問資源的原則

  如果應用程序使用 Active Directory 用戶存儲則應該使用集成 Windows 身份驗證對 ASPNET 應用程序使用集成 Windows 身份驗證時最好的方法是使用 ASPNET 的 Windows 身份驗證提供程序附帶的 Internet 信息服務 (IIS) 身份驗證方法使用該方法將自動創建一個 windowsprincipal 對象(封裝一個 windowsidentity 對象)來表示經過身份驗證的用戶您無需編寫任何身份驗證特定的代碼

  還支持使用 Windows 身份驗證的自定義解決方案(避開了 IIS 身份驗證)例如可以編寫一個根據 Active Directory 檢查用戶憑據的自定義 ISAPI 篩選器使用該方法必須手動創建一個 windowsprincipal 對象

  本文闡釋在具有 IIS 的 ASPNET 中 Windows 身份驗證的工作機制

  IIS 身份驗證

  如果 ASPNET 針對 Windows 身份驗證進行配置則 ASPNET 依靠 IIS利用配置好的身份驗證模式對其客戶端進行身份驗證IIS 通過檢查特定應用程序的元數據庫設置來確定其身份驗證模式成功驗證某個用戶的身份後IIS 將代表經過身份驗證的用戶的 Windows 令牌傳遞給宿主 ASPNET 的 ASPNET 輔助進程 (wwpexe)如果應用程序使用在 IIS 中配置的虛擬目錄來支持匿名訪問該令牌代表匿名 Internet 用戶帳戶否則該令牌代表經過身份驗證的用戶

  iis 支持以下身份驗證模式

  ·匿名如果不需要對客戶端進行身份驗證(或者使用自定義身份驗證機制如窗體身份驗證)則可將 IIS 配置為允許匿名訪問在該事件中IIS 創建一個 Windows 令牌來表示具有相同匿名(或客人)帳戶的所有匿名用戶默認的匿名帳戶是 IUSR_MACHINENAME其中 MACHINENAME 是安裝期間指定的計算機的 NetBIOS 名稱

  ·基本基本身份驗證要求用戶以用戶名和密碼的形式提供憑據來證明他們的身份基本身份驗證基於 Internet 標准 RFC 所有常用浏覽器都支持它用戶的憑據以未加密的 Base 編碼格式從浏覽器傳送到 Web 服務器為了更好保護這些憑據只要在使用基本身份驗證同時再使用安全套接字層 (SSL) 即可由於 Web 服務器包含未加密的用戶憑據因此 ASPNET 應用程序可以模擬調用方並使用他們的憑據來訪問網絡資源

  ·集成的 Windows集成的 Windows 身份驗證(以前稱為 NTLM也稱為 Windows NT 質詢/應答身份驗證Windows NT Challenge/Response)是使用 Kerberos v 身份驗證還是 NTLM 身份驗證取決於客戶端和服務器的配置服務器與客戶端協商確定要使用的協議如果滿足以下條件則使用 Kerberos 身份驗證

  · Web 應用程序正在 NetworkService 帳戶或自定義域帳戶下運行如果應用程序在本地帳戶(如 Windows Server 上的 ASPNET 帳戶)上運行則使用 NTLM 身份驗證

  ·域帳戶的 Active Directory 中有一個服務主要名稱 (SPN)該域帳戶用於運行客戶端進行身份驗證所使用的服務

  ·客戶端計算機和服務器計算機至少需要運行 Windows Server且處在相同的(即信任的)Windows 域中

  注 默認情況下對於 Windows Server 操作系統啟用集成 Windows 身份驗證然而如果 Windows Server Service Pack (SP) 作為 Windows Server 操作系統整合安裝的一部分進行安裝則默認情況下禁用集成 Windows 身份驗證如果使用 SP 升級 Windows Server 則集成 Windows 身份驗證的設置與其 Windows Server 設置相同

  應該使用集成 Windows 身份驗證而不是基本身份驗證因為前者避免了通過網絡傳輸用戶憑據由於 Kerberos v 身份驗證支持相互身份驗證因此用戶還可以對正在連接的服務器進行身份驗證

  集成 Windows 身份驗證最適合於 Intranet 環境其中的客戶端計算機和 Web 服務器計算機都是相同(即信任的)域的一部分

  NTLM身份驗證

  ntlm 是用於 Windows NT 和 Windows Server 工作組環境的身份驗證協議它還用在必須對 Windows NT 系統進行身份驗證的混合 Windows Active Directory 域環境中當 Windows Server 轉換為不存在下層 Windows NT 域控制器的本機模式時禁用 NTLM然後 Kerberos v 變成企業級的默認身份驗證協議

  ntlm 身份驗證機制

  圖 顯示 NTLM 協議

  

  圖 NTLM 質詢/應答機制

  下面概述質詢/應答機制

  · 用戶請求訪問用戶嘗試通過提供用戶憑據登錄到客戶端登錄前客戶端計算機緩存密碼的哈希值並放棄密碼客戶端向服務器發送一個請求該請求包括用戶名以及純文本格式的請求

  · 服務器發送質詢消息服務器生成一個稱為質詢的 字節隨機數(即 NONCE)並將它發送到客戶端

  · 客戶端發送應答消息客戶端使用由用戶的密碼生成的一個密碼哈希值來加密服務器發送的質詢它以應答的形式將這個加密的質詢發回到服務器

  · 服務器將質詢和應答發送到域控制器服務器將用戶名原始質詢以及應答從客戶端計算機發送到域控制器

  · 域控制器比較質詢和應答以對用戶進行身份驗證域控制器獲取該用戶的密碼哈希值然後使用該哈希值對原始質詢進行加密接下來域控制器將加密的質詢與客戶端計算機的應答進行比較如果匹配域控制器則發送該用戶已經過身份驗證的服務器確認

  · 服務器向客戶端發送應答假定憑據有效服務器授予對所請求的服務或資源的客戶端訪問權

  Kerberos 身份驗證

  與 NTLM 身份驗證相比Kerberos 身份驗證具有以下優勢

  · 相互身份驗證當客戶端使用 Kerberos v 協議對特定服務器上的特定服務進行身份驗證Kerberos 為客戶端提供網絡上惡意代碼不會模擬該服務的保證

  · 委托支持使用 Kerberos 身份驗證對客戶端進行身份驗證的服務器可以模擬這些客戶端並使用該客戶端的安全上下文訪問網絡資源

  · 性能Kerberos 身份驗證提供優於 NTLM 身份驗證的改進的性能

  · 簡化的信任管理具有多個域的網絡不再需要一組復雜的顯式點對點信任關系

  · 互操作性Microsoft 實現的 Kerberos 協議基於向 Internet 工程任務組 (IETF) 推薦的標准跟蹤規范因此Windows 中協議的實現為與其他網絡的互操作奠定了基礎(其中 Kerberos 版本 用於身份驗證)

  kerberos 身份驗證機制

  圖 顯示 Kerberos 身份驗證協議的簡化視圖

  

  圖 Kerberos 身份驗證

  當客戶端對網絡服務進行身份驗證之後kerberos v 協議遵循以下步驟

  · 客戶端從 KDC 請求 TGT用戶試圖通過提供用戶憑據登錄到客戶端客戶端計算機上的 Kerberos 服務向密鑰發行中心 (KDC) 發送一個 Kerberos 身份驗證服務請求該請求包含用戶名請求票證授予票證(ticketgranting ticketTGT)所獲取的服務信息以及使用用戶的長期密鑰(即密碼)加密的時間戳

  注 在 Windows Server 或 Windows Server 操作系統上域控制器充當 KDC而 Active Directory 宿主安全帳戶數據庫

  · 身份驗證服務發送加密的 TGT 和會話密鑰KDC 為來自 Active Directory 的用戶獲取長期密鑰(即密碼)然後解密隨請求一起傳送的時間戳如果該時間戳有效則用戶是真正的用戶KDC 身份驗證服務創建一個登錄會話密鑰並使用用戶的長期密鑰對該副本進行加密然後該身份驗證服務創建一個 TGT它包括用戶信息和登錄會話密鑰最後該身份驗證服務使用自己的密鑰加密 TGT並將加密的會話密鑰和加密的 TGT 傳遞給客戶端

  · 客戶端從 TGT 請求服務器訪問客戶端使用其長期密鑰(即密碼)解密登錄會話密鑰並在本地緩存它此外客戶端還將加密的 TGT 存儲在它的緩存中訪問網絡服務時客戶端向 KDC 票證授予服務(ticketgranting serviceTGS)發送一個包含信息的請求這些信息包括用戶名使用用戶登錄會話密鑰加密的驗證者消息TGT以及用戶想訪問的服務(和服務器)名稱

  · TGS 發送加密的會話密鑰和票證KDC 上的 TGS 使用自己的密鑰解密 KDC 並提取登錄會話密鑰它使用該登錄會話密鑰解密驗證者消息(通常是時間戳)如果驗證者消息成功解密TGS 從 TGT 提取用戶信息並使用用戶信息創建一個用於訪問該服務的服務會話密鑰它使用該用戶的登錄會話密鑰對該服務會話密鑰的一個副本進行加密創建一個具有服務會話密鑰和用戶信息的服務票證然後使用該服務的長期密鑰(密碼)對該服務票證進行加密然後TGS 將加密的服務會話密鑰和服務票證添加到客戶端

  · 客戶端發送服務票證客戶端訪問服務時向服務器發送一個請求該請求包含驗證者消息(時間戳)該消息使用服務會話密鑰和服務票證進行加密

  · 服務器發送加密的時間戳以進行客戶端驗證服務器解密服務票證並提取服務會話密鑰通過使用服務會話密鑰服務器解密驗證者消息(時間戳)並計算它如果驗證者通過測試則服務器使用服務會話密鑰對驗證者(時間戳)進行加密然後將驗證者傳回到客戶端客戶端解密時間戳如果該時間戳與原始時間戳相同則該服務是真正的客戶端繼續連接

  服務的主要名稱

  kerberos v 身份驗證協議之所以使用服務的主要名稱 (SPN)原因如下

  · 支持相互身份驗證

  · 允許一個客戶端請求票證進而允許該客戶端與特定服務通訊

  例如如果某個客戶端需要獲得一個票證並對在偵聽端口 運行的計算機 (myserver) 上的特定服務 (myservice) 進行身份驗證則該客戶端使用根據該信息構造的名稱從 KDC 請求一個票證如下所示

  MyService/MyServer在 Active Directory 中注冊的 SPN 在該名稱和運行所請求的服務的域帳戶之間維護一個映射通過使用該機制惡意用戶難以在網絡上模擬服務惡意用戶必須禁用實際服務並從該網絡移除實際服務器然後惡意用戶必須向網絡中添加一台同名的新計算機並公開重復的服務由於客戶端使用具有相互身份驗證的 Kerberos v 協議因此該客戶端將無法使用重復的服務除非它可以提供配置實際服務進行運行的域帳戶的密碼

  ASPNET身份驗證

  iis 向 ASPNET 傳遞代表經過身份驗證的用戶或匿名用戶帳戶的令牌該令牌在一個包含在 iprincipal 對象中的 iidentity 對象中維護iprincipal 對象進而附加到當前 Web 請求線程可以通過 屬性訪問 iprincipal 和 iidentity 對象這些對象和該屬性由身份驗證模塊設置這些模塊作為 HTTP 模塊實現並作為 ASPNET 管道的一個標准部分進行調用如圖 所示

  

  圖 ASPNET 管道

  管道模型包含一個 httpapplication 對象多個 HTTP 模塊對象以及一個 HTTP 處理程序對象及其相關的工廠對象httpruntime 對象用於處理序列的開頭在整個請求生命周期中httpcontext 對象用於傳遞有關請求和響應的詳細信息

  有關 ASPNET 請求生命周期的詳細信息請參閱ASPNET Life Cycle網址是 (enUSVSaspx

  身份驗證模塊

   在計算機級別的 nfig 文件中定義一組 HTTP 模塊其中包括大量身份驗證模塊如下所示

  <httpModules>

  <add name=WindowsAuthentication
    type=SystemWebSecurityWindowsAuthenticationModule />
  <add name=FormsAuthentication
    type=SystemWebSecurityFormsAuthenticationModule />
  <add name=PassportAuthentication
    type=SystemWebSecurityPassportAuthenticationModule />

</httpModules>

  只加載一個身份驗證模塊這取決於該配置文件的 authentication 元素中指定了哪種身份驗證模式該身份驗證模塊創建一個 iprincipal 對象並將它存儲在 屬性中這是很關鍵的因為其他授權模塊使用該 iprincipal 對象作出授權決定

  當 IIS 中啟用匿名訪問且 authentication 元素的 mode 屬性設置為 none 時有一個特殊模塊將默認的匿名原則添加到 屬性中因此在進行身份驗證之後 絕不是一個空引用(在 Visual Basic 中為 nothing)

  windowsauthenticationmodule

  如果 nfig 文件包含以下元素則激活 windowsauthenticationmodule 類

  <authentication mode=Windows />
    WindowsAuthenticationModule 類負責創建 windowsprincipal 和 windowsidentity 對象來表示經過身份驗證的用戶並且負責將這些對象附加到當前 Web 請求

  對於 Windows 身份驗證遵循以下步驟

  · WindowsAuthenticationModule 使用從 IIS 傳遞到 ASPNET 的 Windows 訪問令牌創建一個 windowsprincipal 對象該令牌包裝在 httpcontext 類的 workerrequest 屬性中引發 authenticaterequest 事件時windowsauthenticationmodule 從 httpcontext 類檢索該令牌並創建 windowsprincipal 對象 用該 windowsprincipal 對象進行設置它表示所有經過身份驗證的模塊和 ASPNET 頁的經過身份驗證的用戶的安全上下文

  · WindowsAuthenticationModule 類使用 P/Invoke 調用 Win 函數並獲得該用戶所屬的 Windows 組的列表這些組用於填充 windowsprincipal 角色列表

  · WindowsAuthenticationModule 類將 windowsprincipal 對象存儲在 屬性中隨後授權模塊用它對經過身份驗證的用戶授權

  注defaultauthenticationmodule 類(也是 ASPNET 管道的一部分)將 threadcurrentprincipal 屬性設置為與 屬性相同的值它在處理 authenticaterequest 事件之後進行此操作

  授權模塊

  WindowsAuthenticationModule 類完成其處理之後如果未拒絕請求則調用授權模塊授權模塊也在計算機級別的 nfig 文件中的 httpmodules 元素中定義如下所示

  <httpModules>
  <add name=UrlAuthorization
    type=SystemWebSecurityUrlAuthorizationModule />
  <add name=FileAuthorization
    type=SystemWebSecurityFileAuthorizationModule />
  <add name=AnonymousIdentification
    type=SystemWebSecurityAnonymousIdentificationModule />
</httpModules>

    urlauthorizationmodule

  調用 urlauthorizationmodule 類時它在計算機級別或應用程序特定的 nfig 文件中查找 authorization 元素如果存在該元素則 urlauthorizationmodule 類從 屬性檢索 iprincipal 對象然後使用指定的動詞(GETPOST 等)來確定是否授權該用戶訪問請求的資源

  fileauthorizationmodule

  接下來調用 fileauthorizationmodule 類它檢查 屬性中的 iidentity 對象是否是 windowsidentity 類的一個實例如果 iidentity 對象不是 windowsidentity 類的一個實例則 fileauthorizationmodule 類停止處理

  如果存在 windowsidentity 類的一個實例則 fileauthorizationmodule 類調用 accesscheck Win 函數(通過 P/Invoke)來確定是否授權經過身份驗證的客戶端訪問請求的文件如果該文件的安全描述符的隨機訪問控制列表 (DACL) 中至少包含一個 read 訪問控制項 (ACE)則允許該請求繼續否則fileauthorizationmodule 類調用 方法並將狀態碼 返回到客戶端

  安全上下文

  net Framework 使用以下兩個接口封裝 Windows 令牌和登錄會話

  · SystemSecurityPrincipalIPrincipal

  · SystemSecurityPrincipalIIdentity(它公開為 iprincipal 接口中的一個屬性

  

  在 ASPNET 中用 windowsprincipal 和 windowsidentity 類表示使用 Windows 身份驗證進行身份驗證的用戶的安全上下文使用 Windows 身份驗證的 ASPNET 應用程序可以通過 屬性訪問 windowsprincipal 類

  要檢索啟動當前請求的 Windows 經過身份驗證的用戶的安全上下文使用以下代碼

  using SystemSecurityPrincipal;

// Obtain the authenticated users Identity
WindowsPrincipal winPrincipal = (WindowsPrincipal)HttpContextCurrentUser;

  windowsidentitygetcurrent

  WindowsIdentityGetCurrent 方法可用於獲得當前運行的 Win 線程的安全上下文的標識如果不使用模擬線程繼承 IIS (默認情況下的 NetworkService 帳戶)上進程的安全上下文

  該安全上下文在訪問本地資源時使用通過使用經過身份驗證的初始用戶的安全上下文或使用固定標識您可以使用模擬重寫該安全上下文

  要檢索運行應用程序的安全上下文使用以下代碼

  using SystemSecurityPrincipal;

// Obtain the authenticated users identity
WindowsIdentity winId = WindowsIdentityGetCurrent();
WindowsPrincipal winPrincipal = new WindowsPrincipal(winId);

    threadcurrentprincipal

  應用程序中的每個線程公開一個 currentprincipal 對象該對象保存經過身份驗證的初始用戶的安全上下文該安全上下文可用於基於角色的授權

  要檢索線程的當前原則使用以下代碼

  using SystemSecurityPrincipal;

// Obtain the authenticated users identity
WindowsPrincipal winPrincipal = (WindowsPrincipal) ThreadCurrentPrincipal();

    表 顯示從各種標識屬性獲得的結果標識當您的應用程序使用 Windows 身份驗證且 IIS 配置為使用集成 Windows 身份驗證時可以從 ASPNET 應用程序使用這些標識屬性

   表 線程公開的 CurrentPrincipal Object nfig 設置 變量位置 結果標識

  <identity impersonate=true/>
<authentication mode=Windows />

  HttpContext
WindowsIdentity
線程

  Domain\UserName
Domain\UserName
Domain\UserName

  <identity impersonate=false/>
<authentication mode=Windows />

  HttpContext
WindowsIdentity
線程

  Domain\UserName
NT AUTHORITY\NETWORK SERVICE
Domain\UserName

  <identity impersonate=true/>
<authentication mode=Forms />

  HttpContext
WindowsIdentity
線程

  用戶提供的名稱
Domain\UserName
用戶提供的名稱

  <identity impersonate=false/>
<authentication mode=Forms />

  HttpContext
WindowsIdentity
線程

  用戶提供的名稱
NT AUTHORITY\NETWORK SERVICE
用戶提供的名稱

  模擬

  應用程序可以使用模擬來執行操作使用經過身份驗證的客戶端或特定 Windows 帳戶的安全上下文來訪問資源

  初始用戶模擬

  要模擬初始(經過身份驗證的)用戶請在 nfig 文件中使用以下配置

  <authentication mode=Windows />
<identity impersonate=true />

    使用該配置 始終模擬經過身份驗證的用戶且所有資源訪問均使用經過身份驗證的用戶的安全上下文執行如果您的應用程序的虛擬目錄上啟用了匿名訪問則模擬 IUSR_MACHINENAME 帳戶

  要暫時模擬經過身份驗證的調用方將 identity 元素的 impersonate 屬性設置為 false然後使用以下代碼

  using SystemSecurityPrincipal; // Obtain the authenticated users identity WindowsIdentity winId = (WindowsIdentity)HttpContextCurrentUserIdentity; WindowsImpersonationContext ctx = null; try { // Start impersonating ctx = winIdImpersonate(); // Now impersonating // Access resources using the identity of the authenticated user } // Prevent exceptions from propagating catch { } finally { // Revert impersonation if (ctx != null) ctxUndo(); } // Back to running under the default ASPNET process identity

  這段代碼模擬經過身份驗證的初始用戶在 對象中維護初始用戶的標識和 Windows 令牌

  固定標識模擬

  如果需要在應用程序的整個生命周期中模擬相同的標識可以在 nfig 文件中的 identity 元素上指定憑據以下示例顯示如何模擬名為TestUser的 Windows 帳戶

  如果使用該方法應該對這些憑據進行加密使用 ASPNET 您可以使用 ASPNET IIS 注冊工具 (Aspnet_regiisexe)使用 ASPNET 您可以使用 Aspnet_setregexe 實用工具有關該實用工具的詳細信息請參閱 ?url=/library/enus/cptools/html/cpgrfaspnetiisregistrationtoolaspnet_regiisexeasp

  要在 ASPNET 應用程序中使用固定標識進行資源訪問可使用 Windows Server 或 Windows Server 上的 identity 元素來配置憑據如果正在運行 Windows Server 其中的 IIS 配置為運行在輔助進程隔離模式下(默認情況)則可通過將 ASPNET 應用程序配置為在自定義應用程序池(在特定的域標識下運行)中運行來避免模擬然後可以使用指定的域標識訪問資源而無需使用模擬

  八委托

  模擬只提供對本地資源的訪問委托是一個擴展的模擬功能它允許您使用模擬令牌訪問網絡資源

  如果應用程序使用 Kerberos v 身份驗證對其用戶進行身份驗證則可使用 Kerberos 委托在應用程序的各層傳遞用戶標識並訪問網絡資源如果應用程序不使用 Kerberos v 身份驗證則可使用協議轉換切換到 Kerberos然後使用委托傳遞該標識

  windows Server 中的約束委托需要 Kerberos 身份驗證如果您的應用程序無法使用 Kerberos 身份驗證對其調用方進行身份驗證您可以使用協議轉換從可選的非 Windows 身份驗證模式(如窗體或證書身份驗證)切換到 Kerberos 身份驗證然後可使用具有約束委托的 Kerberos 訪問下游網絡資源

  約束的和未約束的委托

  windows Server 上的 Kerberos 委托是未約束的Active Directory 中配置了委托的服務器可在使用模擬的用戶安全上下文的同時訪問任何網絡資源或網絡上的任何計算機這會帶來潛在的安全威脅尤其是 Web 服務器遭受惡意用戶攻擊時

  為了解決該安全問題windows Server 引入了約束的委托這使管理員能夠在使用模擬的用戶安全上下文時准確指定另一個服務器或域帳戶可以訪問的服務

  配置委托

  要使用 Kerberos 委托需要適當的 Active Directory 配置

  要授予 Web 服務器委托客戶端憑據的權限請按以下方式配置 Active Directory

  · 如果在 NetworkService 帳戶下運行應用程序Web 服務器計算機帳戶必須在 Active Directory 中標記為受信任委托

  · 如果在自定義域帳戶下運行應用程序該用戶帳戶必須在 Active Directory 中標記為受信任委托

  · 如果應用程序模擬一個用戶帳戶請確保應用程序模擬的用戶帳戶在 Active Directory 中未標記為敏感帳戶不能被委托

  有關協議轉換和約束委托的詳細信息請參閱 How To Use Protocol Transition and Constrained Delegation in ASPNET



From:http://tw.wingwit.com/Article/program/net/201311/13414.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.