ASP.NET2.0里的配置接口API ASP.NET2.0里的配置API接口函數(shù)允許我們讀/寫配置文件----包括對web.config和machine.config的讀寫。您可以讀寫您自己應(yīng)用程序里的配置文件,也可以讀寫同一機(jī)器上其它應(yīng)用程序的配置文件,您甚至可以讀寫不同服務(wù)器上的應(yīng)用程序配置文件。本文我們將以ASP.NET開發(fā)人員的角度看一下ASP.NET2.0的新亮點(diǎn),這其中包括如何加密和解密配置文件。
AppSettings 和 Connection 字符串 在ASP.NET開發(fā)中,兩個(gè)常規(guī)任務(wù)是從配置文件里讀取應(yīng)用程序的設(shè)置和數(shù)據(jù)庫鏈接字符串。在ASP.NET2.0中,這些設(shè)置分別駐留在<appSettings>和<connectionStrings>配置節(jié)。一個(gè)web.config示例看起來應(yīng)該類似如下: <?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <appSettings> <add key="message" value="Hello World!" /> </appSettings>
<connectionStrings> <add name="AdventureWorks" connectionString="..."/> <add name="pubs" connectionString="..."/> </connectionStrings>
<system.web> <compilation debug="true" /> <authentication mode="Windows"/> <identity impersonate="true"/> </system.web> </configuration>
ASP.NET提供的API接口函數(shù)是以WebConfigurationManager類開始的,該類在System.Web.Configuration命名空間。WebConfigurationManager類包含了靜態(tài)方法以獲取應(yīng)用程序的設(shè)置和數(shù)據(jù)庫連接字符串。例如為了讀取上面示例中appSetting的“message”信息,我們可以使用類似如下的代碼: string message; message = WebConfigurationManager.AppSettings["message"]; 同樣,如果我們想獲取第二個(gè)數(shù)據(jù)庫連接字符串--連接名為pubs的--我們可以使用如下的代碼 string connectionString = WebConfigurationManager.ConnectionStrings["pubs"].ConnectionString;
通過使用GetSection靜態(tài)方法,使得讀取配置文件里的任何設(shè)置變的簡單。GetSection采用XPath表達(dá)式來響應(yīng)你想讀取的節(jié),你可以使用強(qiáng)類型轉(zhuǎn)換將對對象的引用轉(zhuǎn)換為對內(nèi)置節(jié)的引用。例如使用AuthorizationSection 類來操作對<authorization>節(jié)的配置,使用PageSection類來操作對<pages>節(jié)的操作。
如果我們想更改web.config里對<identity>節(jié)模擬的設(shè)置,我們可以使用如下代碼 protected void readImpersonationButton_Click(object sender, EventArgs e)
{ // note: currently broken in BETA2, works in post BETA2 builds. // in BETA2 GetSection returns a wrapper // that will not cast to IdentitySection IdentitySection section; section = WebConfigurationManager.GetSection("system.web/identity") as IdentitySection;
if (section != null) { WriteMessage("Impersonate = " + section.Impersonate); } }
private void WriteMessage(string message) { // this method assumes a PlaceHolder control // on the web form with the ID of messagePlaceHolder HtmlGenericControl generic = new HtmlGenericControl(); generic.InnerHtml = message; messagePlaceHolder.Controls.Add(generic); }
protected void readImpersonationButton_Click(object sender, EventArgs e)
{ System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration(path);
WebConfigurationManager 類提供靜態(tài)方法OpenWebConfiguration同樣允許我們打開web的配置文件并進(jìn)行更新。我們可以通過根據(jù)傳遞應(yīng)用程序的相對路徑來指明需要打開哪個(gè)應(yīng)用程序的配置文件。我們還可以通過傳遞IIS 站點(diǎn)名稱和虛擬路徑的名稱來讀取其它應(yīng)用程序的配置問題。使用后面這種方式,就可以讀取其它應(yīng)用程序的配置文件。 如果我們想獲取當(dāng)前應(yīng)用程序web.config里<compliation>配置節(jié)的debug屬性,更改debug為true或者為false,我們可以使用在button的事件里使用如下代碼 protected void toggleDebugButton_Click(object sender, EventArgs e) { Configuration config; config = WebConfigurationManager.OpenWebConfiguration(path); CompilationSection compilation; compilation = config.GetSection("system.web/compilation") as CompilationSection;
if (compilation != null) { compilation.Debug = !compilation.Debug; config.Save(); WriteMessage( "Debug setting is now: " + compilation.Debug ); } }
使用強(qiáng)類型的CompilationSection對象允許我們讀寫<compliation>節(jié)里的屬性。我們可以改變節(jié)的配置并使用 System.Configuration.Configuration 里的Save保存所有的修改。 在更改配置文件時(shí),還有一個(gè)小的細(xì)節(jié),首先,你應(yīng)該具有修改配置文件的權(quán)限,典型的啟動.NET runtime運(yùn)行時(shí)的NETWORD SERVICE和ASPNET帳戶并沒有修改應(yīng)用程序里配置文件的權(quán)限。 一個(gè)安全的解決方法是使用基于windows的身份驗(yàn)證并啟用模擬技術(shù)。這些設(shè)置允許客戶端執(zhí)行請求的任務(wù)。如果客戶端具有修改配置文件的權(quán)限,上面的操作才能夠成功。 另外一個(gè)注意事項(xiàng)是ASP.NET runtime將隨時(shí)監(jiān)視web.config,一旦web.config有了改動,ASP.NET將重新啟動應(yīng)用程序。具體的說 ASP.NET運(yùn)行時(shí)將根據(jù)你更改web.config所在的應(yīng)用程序域,重新建立應(yīng)用程序?qū)ο髮?shí)例。重建實(shí)例對性能有顯著影響,所以不應(yīng)該經(jīng)常修改web.config。 如果你想要在修改web.config時(shí),既能夠獲取更多的控制權(quán)限同時(shí)又不使應(yīng)用程序重新啟動,你可以使用外部配置文件,下一節(jié)將介紹這個(gè)問題。
使用外部配置文件 你可以將配置文件里的任意配置節(jié)取出并單獨(dú)存放,例如我們看一下新的配置web.config文件 <?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <appSettings configSource="appSettings.config"/> <connectionStrings configSource="connections.config"/> <system.web> <compilation debug="true" /> <authentication mode="Windows"/> <identity impersonate="true"/> </system.web> </configuration>
在這個(gè)例子中,我們將<appSettings> 和 <connectionStrings>的配置移動到了web.config的外部,這些外部文件同樣是基于XML格式的配置節(jié)片段,例如appSettings.config的文件看起來類似如下: <appSettings> <add key="message" value="Hello World!"/> </appSettings>
使用外部配置文件在某些情況下較為有用,例如在開發(fā),或者在測試甚至在成品軟件開發(fā)中,由于階段的不同我們需要一種簡易的方式切換設(shè)置,此時(shí)就可以使用外部配置文件。 如果你需要更多的控制權(quán)限也可以使用外部配置,例如你對你的web.config進(jìn)行了鎖定,只有Administrators用戶可以更改該配置問題,但是你可以讓<appSettings>節(jié)使用外部配置文件并允許其它角色的用戶修改其內(nèi)容。 使用外部文件還有其它的優(yōu)越性--它可以控制我們的應(yīng)用程序是否重新啟動。 如果在web.config里進(jìn)行了改動。ASP.NET應(yīng)用程序總會重新啟動--不存在選擇的余地,但是使用外部文件,你可以告訴runtime運(yùn)行時(shí),是否在外部文件改動時(shí)重啟應(yīng)用程序。
如果你查看machine.config里的配置,在<configSections>節(jié),你可以看到每一個(gè)節(jié)定義的處理句柄(Handler)。每一個(gè)節(jié)包含一個(gè)屬性:restartOnExternalChanges。 請注意對appSettings的配置,其restartOnExternalChanges設(shè)置為"false",這意味這如果使用外部文件存放設(shè)置信息,當(dāng)外部文件改變時(shí),應(yīng)用程序并不重新啟動,但是你使用WebConfigurationManager.AppSettings讀取的將是新值。 在使用restartOnExternalChanges 請注意,有些外部文件改變時(shí),必須重啟應(yīng)用程序才能夠生效。在這種情況下,雖然你可以設(shè)置restartOnExternalChanges 為false,但是請確保不要在應(yīng)用程序里緩存節(jié)的參數(shù),并重新使用WebConfigurationManager讀取配置值。
使用加密 在ASP.NET2.0里提供了對配置節(jié)直接加密的功能。在配置文件里有幾處配置可能包含敏感信息,例如<connectionStrings> 節(jié),它可能包含連接數(shù)據(jù)庫的用戶名和密碼。<identity>節(jié)可能包含runtime使用模擬帳戶的用戶和密碼。 你甚至可能在配置文件的appSettings里或者在自定義節(jié)里包含共享web service使用的密碼。不管哪種情況,您都不希望密碼以明文的方式存放在配置文件里。 注意:在配置文件里也包含你無法加密的節(jié),主要是<precessModul>節(jié)。此時(shí)你可以需要利用ASPNET_SETREG.EXE工具單獨(dú)設(shè)置該節(jié)密碼。
下面的代碼演示了加密和解密節(jié)是多么的簡單,注意:在從節(jié)里讀取配置信息時(shí),你不需要解密。ASP.NET運(yùn)行時(shí)會自動讀取加密的文本,并在應(yīng)用程序需要的地方自動解密加密的信息。在這里調(diào)用Unprotect方法主要是演示如何返回未加密的節(jié)
protected void toggleEncryptionButton_Click(object sender, EventArgs e) { Configuration config; config = WebConfigurationManager.OpenWebConfiguration("~"); ConnectionStringsSection section; section = config.GetSection("connectionStrings") as ConnectionStringsSection; if (section.SectionInformation.IsProtected) { section.SectionInformation.UnprotectSection(); }
else { section.SectionInformation.ProtectSection( "DataProtectionConfigurationProvider" ); } config.Save(); WriteMessage("connections protected = " + section.SectionInformation.IsProtected); }
在執(zhí)行上述代碼后,如果我們檢測web.config,我們將看到其配置如下: <?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <protectedData> <protectedDataSections> <add name="connectionStrings" provider="DataProtectionConfigurationProvider" inheritedByChildren="false" /> </protectedDataSections> </protectedData> <appSettings configSource="appSettings.config"/> <connectionStrings configSource="connections.config"/>
<system.web> <compilation debug="true" /> <authentication mode="Windows"/> <identity impersonate="true"/> </system.web> </configuration>
這里我們使用的是外部配置文件, 打開外部配置文件可以看到內(nèi)容類似如下:
<connectionStrings> <EncryptedData> <CipherData> <CipherValue>AQAAANCMnd8BF....</CipherValue> </CipherData> </EncryptedData> </connectionStrings>
運(yùn)行時(shí),ASP.NET解密區(qū)域信息,我們可以仍然使用WebConfigurationManager.ConnectionStrings 返回應(yīng)用程序可以直接使用的數(shù)據(jù)庫連接字符串。
為了理解配置文件,我們首先需要明白名運(yùn)行時(shí)是怎么處理加密和解密工作的。解密和解密分別使用了Provider模型,ASP.NET2.0使用這兩個(gè)Provider模型分別是:DataProtectionConfigurationProvider 和RSAProtectedConfigurationProvider (如果需要,你也可以自定義自己的加密/解密Provider) 我們可以通過傳遞給ProtectSetion的參數(shù)來指示使用Provider的具體模型。在前面代碼片段中,我們使用的是DataProtectionConfigurationProvider
DataProtectionConfigurationProvider 使用Windows Data Protection API (DPAPI)接口,這提供了加密和解密的工作,因?yàn)?/span>Windows Data Protection API (DPAPI)依賴于具體的機(jī)器密鑰。只有在同一機(jī)器上,針對加密的解密才有效。
如果你需要將配置從一臺機(jī)器轉(zhuǎn)移到另外一臺機(jī)器,你需要使用RSAProtectedConfigurationProvider模型。RSAProtectedConfigurationProvider,正如其名稱所示意,使用RSA作為加密密鑰。 你可以使用具有RSAProtectedConfigurationProvider功能的aspnet_regiis.exe命令進(jìn)行操作。aspnet_regiis.exe包含一些列參數(shù)包括建立密鑰對(-pc),導(dǎo)出密碼(-pc)等
總結(jié) 本文介紹了如何使用API配置函數(shù)讀寫配置文件。在配置文件修改時(shí),討論了應(yīng)用程序的重啟問題。
源文地址 http:///Articles/418.aspx |
|