程式碼存取安全性和 ADO.NET
Windows 安全性可讓您依照使用者角色控制資源的存取。例如,Windows 的系統管理員群組之成員資格即給予系統管理員不受限制的使用權限,而來賓使用者的存取則非常有限。
在 Unmanaged 程式碼的作用範圍內,大多數應用程式都是以使用者的使用權限執行,這使得他們很難對程式碼套用限制。因此,當惡意或充滿錯誤的軟體開始執行時,就可能損害電腦系統和竊取私人資料。
相反地,.NET Framework 中所執行的 Managed 程式碼有一個稱為程式碼存取安全性的安全性機制,可讓系統根據程式碼的來源和其他識別資訊,對該程式碼指定不同的信任等級。這能降低 Managed 程式碼被誤用的可能性。
ADO.NET 和程式碼存取安全性
執行程式碼時,它會顯示 Common Language Runtime (CLR) 安全性系統所評估的辨識項。一般來說,這個辨識項會洩露程式碼的來源,包含 URL、大小和區域,以及用來確保組件識別的數位簽章。
接下來根據這個辨識項,將一組使用權限授與程式碼。應用程式可正確執行,或產生 SecurityException。本機電腦的 System.Security.Policy 設定可決定程式碼所接收的使用權限。如需詳細資訊,請參閱設定安全性原則及安全性原則管理。
使用權限集合通常分為以下三個類別:
類別 | 說明 |
---|---|
完全信任 |
表示程式碼沒有限制,且預設是使用於本機電腦和具有強式名稱的來源。 |
部分信任 |
包含適用於特定區域的使用權限和限制的組合。 |
未受信任 |
表示區域沒有使用權限集合。程式碼可能只使用不需要使用權限的功能。 |
CLR 中執行的程式碼不能授與其本身的使用權限。如需執行階段如何決定授與何種使用權限的詳細資訊,請參閱機器碼和 .NET Framework 程式碼中的安全性。
ADO.NET 2.0 中的部份信任
在 ADO.NET 2.0 中,SQL Server 的 .NET Framework 資料提供者 (System.Data.SqlClient)、OLE DB 的 .NET Framework 資料提供者、ODBC 的 .NET Framework 資料提供者和 Oracle 的 .NET Framework 資料提供者現在都可以在部份信任的環境下執行。在舊版的 .NET Framework 中,只有 System.Data.SqlClient 才能在低於完全信任的應用程式中使用。
使用 SQL Server 提供者的部份信任應用程式至少必須具有執行和 SqlClientPermission 使用權限。
部份信任的使用權限屬性
在部份信任案例中,可使用 SqlClientPermissionAttribute 成員進一步限制 .NET Framework Data Provider for SQL Server 的可用功能。
注意事項 |
---|
.NET Framework Data Provider for SQL Server 需要有「完全信任安全性」使用權限,才能在啟用 SQL Server 2000 之 SQL 偵錯的情況下開啟 SqlConnection。SQL Server 2005 的 SQL 偵錯不會使用這個類別。如需詳細資訊,請參閱《SQL Server 2005 線上叢書》。 |
下列表格列出可用的 SqlClientPermissionAttribute 屬性及其說明:
使用權限屬性 | 說明 | ||
---|---|---|---|
Action |
取得或設定安全性動作。繼承自 SecurityAttribute。 |
||
AllowBlankPassword |
啟用或停用在連接字串中使用空白密碼。有效值為 true 表示啟用空白密碼,而 false 表示停用空白密碼。繼承自 DBDataPermissionAttribute。 |
||
ConnectionString |
識別允許的連接字串。可識別多個連接字串。
繼承自 DBDataPermissionAttribute。 |
||
KeyRestrictions |
識別是否為允許的連接字串參數。連接字串參數是以格式 <parameter name>= 識別的。也可以指定多個參數,只要以分號 (;) 將其分隔即可。 注意若未指定 KeyRestrictions,卻將 KeyRestrictionBehavior 屬性設為 AllowOnly 或 PreventUsage,則不允許其他連接字串參數。繼承自 DBDataPermissionAttribute。 |
||
KeyRestrictionBehavior |
將連接字串參數識別為唯一允許的其餘參數 (AllowOnly),或識別不允許的其餘參數 (PreventUsage))。預設值為 AllowOnly。繼承自 DBDataPermissionAttribute。 |
||
TypeID |
在衍生類別中實作時,取得唯一識別項。繼承自 Attribute。 |
||
Unrestricted |
指示是否針對資源,宣告不受限的使用權限。繼承自 SecurityAttribute。 |
ConnectionString 語法
下列範例示範如何使用組態檔的 connectionStrings 項目,只允許使用特定的連接字串。如需從組態檔儲存和擷取連接字串的詳細資訊,請參閱使用連接字串。
<connectionStrings>
<add name="DatabaseConnection"
connectionString="Data Source=(local);Initial
Catalog=Northwind;Integrated Security=SSPI;" />
</connectionStrings>
KeyRestrictions 語法
下列範例啟用相同的連接字串,同時也啟用 Encrypt 和 Packet Size 連接字串選項,但限制使用任何其他連接字串選項。
<connectionStrings>
<add name="DatabaseConnection"
connectionString="Data Source=(local);Initial
Catalog=Northwind;Integrated Security=SSPI;"
KeyRestrictions="Encrypt=;Packet Size=;"
KeyRestrictionBehavior="AllowOnly" />
</connectionStrings>
含 PreventUsage 的 KeyRestrictionBehavior 語法
下列範例啟用相同的連接字串,並允許 User Id、Password 和 Persist Security Info 以外的其他所有連接參數。
<connectionStrings>
<add name="DatabaseConnection"
connectionString="Data Source=(local);Initial
Catalog=Northwind;Integrated Security=SSPI;"
KeyRestrictions="User Id=;Password=;Persist Security Info=;"
KeyRestrictionBehavior="PreventUsage" />
</connectionStrings>
含 AllowOnly 的 KeyRestrictionBehavior 語法
下列範例啟用兩個連接字串,這兩個連接字串同時包含 Initial Catalog、Connection Timeout、Encrypt 和 Packet Size 參數。所有其他的連接字串參數則都限制使用。
<connectionStrings>
<add name="DatabaseConnection"
connectionString="Data Source=(local);Initial
Catalog=Northwind;Integrated Security=SSPI;"
KeyRestrictions="Initial Catalog;Connection Timeout=;
Encrypt=;Packet Size=;"
KeyRestrictionBehavior="AllowOnly" />
<add name="DatabaseConnection2"
connectionString="Data Source=SqlServer2;Initial
Catalog=Northwind2;Integrated Security=SSPI;"
KeyRestrictions="Initial Catalog;Connection Timeout=;
Encrypt=;Packet Size=;"
KeyRestrictionBehavior="AllowOnly" />
</connectionStrings>
以自訂的使用權限集啟用部份信任
若要啟用特定區域的 System.Data.SqlClient 使用權限,系統管理員必須建立自訂的使用權限集合,並將其設定為特定區域的使用權限集合。不可修改預設的使用權限集合 (例如 LocalIntranet)。例如,若要併入具有 LocalIntranet 之 Zone 的程式碼的 System.Data.SqlClient 使用權限,系統管理員可以複製 LocalIntranet 的使用權限集合、將它重新命名為 "CustomLocalIntranet"、加入 System.Data.SqlClient 使用權限、使用程式碼存取安全性原則工具 (Caspol.exe) 匯入 CustomLocalIntranet 使用權限集合,然後將 LocalIntranet_Zone 的使用權限集合設為 CustomLocalIntranet。
使用權限集合範例
下列是部份受信任案例中的「 SQL Server 的 .NET Framework 資料提供者」使用權限集合範例。如需建立自訂使用權限集合的詳細資訊,請參閱使用 Caspol.exe 設定使用權限集合。
<PermissionSet class="System.Security.NamedPermissionSet"
version="1"
Name="CustomLocalIntranet"
Description="Custom permission set given to applications on the local intranet">
<IPermission class="System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
AllowBlankPassword="False">
<add ConnectionString="Data Source=(local);Integrated Security=SSPI;"
KeyRestrictions="Initial Catalog=;Connection Timeout=;Encrypt=;Packet Size=;"
KeyRestrictionBehavior="AllowOnly" />
</IPermission>
</PermissionSet>
使用安全性使用權限驗證 ADO.NET 程式碼存取
若為部份信任案例,則可指定 SqlClientPermissionAttribute,取得程式碼中之特定方法的程式碼存取安全性權限。如果生效的限制安全性原則不允許該權限,則在執行程式碼前會擲回例外狀況。如需安全性原則的詳細資訊,請參閱安全性原則管理和安全性原則的最佳作法。
範例
下列範例示範如何撰寫需要特定連接字串的程式碼。它模擬如何拒絕 System.Data.SqlClient 的不受限使用權限,而系統管理員在實務上會使用程式碼存取安全性原則來實作這些使用權限。使用 ADO.NET 的程式碼存取安全性使用權限時,最正確的模式是以最大的限制 (完全沒有使用權限) 開始,然後加入程式碼執行的特殊工作所需的特定使用權限。相反地,如果以所有使用權限開始,再嘗試拒絕特定設定權限,並不是安全的作法,因為有許多方法可表示相同的連接字串。例如,如果您以所有使用權限開始,然後拒絕連接字串 "server=someserver" 用法,您仍可使用 "server=someserver.mycompany.com"。以不含任何使用權限開始,就能確保使用權限集合不會有漏洞。
下列程式碼示範 SqlClient 如何執行安全性需求,也就是在沒有適當的程式碼存取安全性使用權限時,擲回 SecurityException。主控台視窗會顯示 SecurityException 輸出。
Public Sub CreateOdbcParameter()
Dim myParameter As New OdbcParameter("Description", OdbcType.VarChar, _
11, ParameterDirection.Output, True, 0, 0, "Description", _
DataRowVersion.Current, "garden hose")
Console.WriteLine(myParameter.ToString())
End Sub
public void CreateOdbcParameter()
{
OdbcParameter myParameter = new OdbcParameter(
"Description", OdbcType.VarChar, 11,
ParameterDirection.Output, true, 0, 0, "Description",
DataRowVersion.Current, "garden hose");
Console.WriteLine(myParameter.ToString());
}
您應該在 [主控台] 視窗中看到以下輸出:
Failed, as expected: <IPermission class="System.Data.SqlClient.
SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" AllowBlankPassword="False">
<add ConnectionString="Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI" KeyRestrictions=""
KeyRestrictionBehavior="AllowOnly"/>
</IPermission>
Connection opened, as expected.
Failed, as expected: Request failed.