使用WIF實現單點登錄Part I——Windows Identity Foundation介紹及環境搭建


轉自:http://blog.csdn.net/ojlovecd/article/details/8572335

個月有一個星期的時間都在研究asp.net mvc統一身份驗證及單點登錄的實現。經過了一番的探索,最終決定使用微軟的Windows Identity Foundation。但是這東西用的人貌似不多,而且中文資料甚少,所以在測試的過程中走了不少彎路,所以寫下這一系列文章,希望能對以后要使用的朋友帶來一點幫助。

首先先說一下什么是WIF(Windows Identity Foundation)。由於各種歷史原因,身份驗證和標識的管理一般都比較無規律可循。在軟件里加入“身份驗證”功能意味着要在你的代碼里混進處理底層任務(如驗證用戶名和密碼,與X509證書或類似的證書打交道等)的代碼。這樣一來就得對基礎架構相當依賴,程序很難移植,除非大范圍重寫。要改變這種情況,使用基於聲明的標識(claims-based identity)可以很好的解決這個問題。這個“基於聲明的標識”是神馬東西我們留到以后再講,現在您只要知道有這么個東西就行了。Windows Identity Foundation(WIF)是微軟的基於聲明標識的協議棧。它是一個新的基礎技術,可以幫助.NET開發人員利用基於聲明的方法來處理身份驗證,授權,定制化以及任何與標識相關的任務,而無需編寫任何底層代碼。

下面來說說WIF環境的搭建。在這里我就走了不少冤枉路。我的悲催經歷就不跟大家分享了,直接介紹各種環境該如何搭建:

1、如果你已經安裝了VS2012,那么WIF已經包含在了.Net Framework當中,而且版本為WIF4.5。但是注意,WIF4.5只能用於.net 4.5的工程,如果你的asp.net或MVC項目是基於.net 4.5以下的話(即使你是在VS2012里創建的工程),請繼續參考以下方法。

2、如果你安裝的是VS2010/VS2008,那么你首先要先安裝WIF,然后安裝WIF SDK。

如果你用的是windows 8,那么系統已經集成了Windows Identity Foundation 3.5了,只要打開控制面板->程序和功能->打開或關閉Windows功能,找到 Windows Identity Foundation 3.5 ,將前面的勾勾上,然后點擊“確定”,完事兒以后點“關閉”即可,如圖:

 Quick tip: Enable Windows Identity Foundation (Windows 8)

這樣WIF 3.5就啟用成功了。

如果是其它操作系統,請點擊這里,找到對應操作系統的exe文件,下載安裝即可。

3、接下來安裝WIF的SDK,如果你用的是VS2012,那就不用裝任何SDK了,因為它都已經集成在.Net Framework 4.5里了。但是你可能需要安裝一個VS的插件。打開VS2012,點擊工具->擴展和更新,在左邊列表里點擊“聯機”,然后在右上角的搜索框里輸入"identity",點擊搜索結果里的“Identity and Access Tool”,點擊下載按鈕,等待下載並安裝完成就可以了。這個工具可以讓你很快捷地為Web Application,MVC程序或者WCF服務增加一個本地開發STS(Local Development STS),來測試WIF的功能。這個工具的使用我們留到以后再講。

如果你用的不是VS2012,請點擊這里進行下載並安裝相應的SDK。

 

至此,WIF所需的環境就已經搭建好了,下一步我們來通過一個小例子來說明WIF的工作原理。

這里我用的環境是win7+vs2012,vs2010+WIF3.5/4.0的情況請參見這篇文章

 

打開VS2012,新建一個基於.net framework4.5的MVC4的工程,取名為WIFTutorial。如下圖:

在彈出的“新ASP.NET MVC 4項目”對話框中直接點“確定”。

項目新建完畢后,在“解決方案資源管理器”中,項目名稱上點右鍵,然后選擇“Identity and Accee...”,如圖:

在“Providers”頁簽里選擇“Use the Local Development STS to test your application”。此時”Local Development STS"頁簽由不可用變為可用。切換到該頁簽,將Test claims to issue表格里的第一行的Value列改為“ojlovecd”,如圖:

點擊“OK”,這個工具將會更改你的web.config文件,我們在解決方案資源管理器里打開web.config看看:

 

[html]  view plain  copy
 
 print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!--  
  3.   有關如何配置 ASP.NET 應用程序的詳細信息,請訪問  
  4.   http://go.microsoft.com/fwlink/?LinkId=169433  
  5.   -->  
  6. <configuration>  
  7.   <configSections>  
  8.     <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->  
  9.     <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />  
  10.     <span style="color:#ff0000;"><section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />  
  11.     <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /></span>  
  12.   </configSections>  
  13.   <connectionStrings>  
  14.     <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-WIFTutorial-20130220231745;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-WIFTutorial-20130220231745.mdf" providerName="System.Data.SqlClient" />  
  15.   </connectionStrings>  
  16.   <appSettings>  
  17.     <add key="webpages:Version" value="2.0.0.0" />  
  18.     <add key="webpages:Enabled" value="false" />  
  19.     <add key="PreserveLoginUrl" value="true" />  
  20.     <add key="ClientValidationEnabled" value="true" />  
  21.     <add key="UnobtrusiveJavaScriptEnabled" value="true" />  
  22.     <span style="color:#ff0000;"><add key="ida:FederationMetadataLocation" value="http://localhost:14419/wsFederationSTS/FederationMetadata/2007-06/FederationMetadata.xml" />  
  23.     <add key="ida:Issuer" value="http://localhost:14419/wsFederationSTS/Issue" />  
  24.     <add key="ida:ProviderSelection" value="localSTS" /></span>  
  25.   </appSettings>  
  26.   <span style="color:#ff0000;"><location path="FederationMetadata">  
  27.     <system.web>  
  28.       <authorization>  
  29.         <allow users="*" />  
  30.       </authorization>  
  31.     </system.web>  
  32.   </location></span>  
  33.   <system.web>  
  34.     <span style="color:#ff0000;"><authorization>  
  35.       <deny users="?" />  
  36.     </authorization></span>  
  37.     <authentication mode="None" />  
  38.     <compilation debug="true" targetFramework="4.5" />  
  39.     <httpRuntime targetFramework="4.5" requestValidationMode="4.5" />  
  40.     <!--Commented by Identity and Access VS Package-->  
  41.     <!--<authentication mode="Forms"><forms loginUrl="~/Account/Login" timeout="2880" /></authentication>-->  
  42.     <pages>  
  43.       <namespaces>  
  44.         <add namespace="System.Web.Helpers" />  
  45.         <add namespace="System.Web.Mvc" />  
  46.         <add namespace="System.Web.Mvc.Ajax" />  
  47.         <add namespace="System.Web.Mvc.Html" />  
  48.         <add namespace="System.Web.Optimization" />  
  49.         <add namespace="System.Web.Routing" />  
  50.         <add namespace="System.Web.WebPages" />  
  51.       </namespaces>  
  52.     </pages>  
  53.   </system.web>  
  54.   <system.webServer>  
  55.     <validation validateIntegratedModeConfiguration="false" />  
  56.     <handlers>  
  57.       <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />  
  58.       <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />  
  59.       <remove name="ExtensionlessUrlHandler-Integrated-4.0" />  
  60.       <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />  
  61.       <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />  
  62.       <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />  
  63.     </handlers>  
  64.     <modules>  
  65.       <remove name="FormsAuthentication" />  
  66.       <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />  
  67.       <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />  
  68.     </modules>  
  69.   </system.webServer>  
  70.   <runtime>  
  71.     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
  72.       <dependentAssembly>  
  73.         <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />  
  74.         <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />  
  75.       </dependentAssembly>  
  76.       <dependentAssembly>  
  77.         <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />  
  78.         <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />  
  79.       </dependentAssembly>  
  80.       <dependentAssembly>  
  81.         <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />  
  82.         <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />  
  83.       </dependentAssembly>  
  84.     </assemblyBinding>  
  85.   </runtime>  
  86.   <entityFramework>  
  87.     <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">  
  88.       <parameters>  
  89.         <parameter value="v11.0" />  
  90.       </parameters>  
  91.     </defaultConnectionFactory>  
  92.   </entityFramework>  
  93.   <system.identityModel>  
  94.     <identityConfiguration>  
  95.       <audienceUris>  
  96.         <add value="http://localhost:8007/" />  
  97.       </audienceUris>  
  98.       <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">  
  99.         <trustedIssuers>  
  100.           <add thumbprint="9B74CB2F320F7AAFC156E1252270B1DC01EF40D0" name="LocalSTS" />  
  101.         </trustedIssuers>  
  102.       </issuerNameRegistry>  
  103.       <certificateValidation certificateValidationMode="None" />  
  104.     </identityConfiguration>  
  105.   </system.identityModel>  
  106.   <span style="color:#ff0000;"><system.identityModel.services>  
  107.     <federationConfiguration>  
  108.       <cookieHandler requireSsl="false" />  
  109.       <wsFederation passiveRedirectEnabled="true" issuer="http://localhost:14419/wsFederationSTS/Issue" realm="http://localhost:8007/" requireHttps="false" />  
  110.     </federationConfiguration>  
  111.   </system.identityModel.services></span>  
  112. </configuration>  


其中標紅色的部分即為工具自動生成的。同時此工具還會在你的程序跟目錄下新建了一個名為FederationMetadata的目錄,通過在解決方案資源管理器中點擊“顯示所有文件”按鈕就可以看到了。

 

 

然后我們按F5,結果報錯了,如圖:

看提示,是因為要啟動LocalSTS必須要用管理員身份來運行。好吧,關掉VS,以管理員身份再次打開,載入項目,再次按F5運行程序,此時看到右下角托盤處LocalSTS已經運行了,而打開的主頁中,右上角顯示用戶ojlovecd已經處於登錄狀態。

 

這一連串操作到底都干了什么?

首先,剛才已經說到,Identity and Access Tool先修改了web.config,增加了WIF要用到的一些配置信息,在程序啟動的時候,首先一並啟動LocalSTS,這個LocalSTS起什么作用?由於web.config中配置了authorization節點,拒絕匿名用戶訪問,因此在你的程序運行起來以后,對程序的請求信息被重定向到LocalSTS,向LocalSTS請求身份信息,LocalSTS收到請求后,返回身份信息。那么返回的身份信息怎么來的?沒錯,就是在Identity and Access Tool工具里的第三個頁簽里配置的。

 

至此,我們沒有編寫任何代碼,就已經實現了一個很簡單的身份驗證功能,關於此例子的詳細講解,以及我們要重點介紹的WIF原理及單點登錄的實現,我們將留到下面的文章進行講解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM