方法 : RequestMinimum フラグを使用して最小のアクセス許可を要求する
重要
.NET Framework Version 4 では、Deny、RequestMinimum、RequestOptional、および RequestRefuse の各アクセス許可要求を適用するためのランタイム サポートは削除されています。これらの要求は、.NET Framework 4 以降に基づくコードで使用しないでください。この変更およびその他の変更の詳細については、「.NET Framework 4 におけるセキュリティの変更点」を参照してください。
RequestMinimum フラグを使用すると、コードを実行するために必要な最小のアクセス許可セットを要求できます。これとは反対に、RequestRefuse フラグを使用すると、コードに付与しないアクセス許可を明示的に指定することにより、これらのアクセス許可を拒否できます。
また、RequestOptional フラグを使用してアクセス許可を要求することもできます。この場合、アプリケーションは、要求したアクセス許可のすべてを受信しない場合でも実行されます。アプリケーションが保護されたリソースへのアクセスを試みると、SecurityException がスローされます。このような要求を使用する場合は、オプションのアクセス許可が与えられなかった場合にスローされる例外を、そのコードがキャッチできるようにしておく必要があります。
次の手順の Test 例では、RequestMinimum フラグを使用することにより、FileIOPermission を要求します。要求したアクセス許可が与えられていない場合、この例は実行されません。既定では、この例をデスクトップで実行すると、完全信頼が与えられて、常に実行されます。RequestMinimum フラグをテストするには、この例を FileIOPermission を付与しない部分信頼ゾーンに読み込む必要があります。次の手順では、LocalIntranet ゾーン用のサンドボックスと、FileIOPermission を要求するテスト アプリケーションを作成します。RequestMinimum の使い方を示すために、テスト アプリケーションをサンドボックス内で実行します。アプリケーションが読み込まれると、例外がスローされます。
サンドボックスでアプリケーションを実行するには
Visual Studio で、コンソール アプリケーション プロジェクトを作成します。
「使用例」のコードを、アプリケーション ファイルにコピーします。このコードは、LocalIntranet アクセス許可セットで実行されるサンドボックスを作成します。LocalIntranet アクセス許可セットは、FileIOPermission を含みません。
[プロジェクト] メニューの [プロパティ] をクリックし、[署名] タブをクリックして、厳密名キーでプロジェクトに署名します。
Test という名前の新しいコンソール アプリケーション プロジェクトをソリューションに追加します。
Test のアプリケーション ファイルに次のコードをコピーします。このコードは、FileIOPermission を最小要件として要求します。これを付与できない場合、SecurityException がスローされます。
Imports System Imports System.Security.Permissions Imports System.IO <Assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted:=True)> Namespace Test Class Program Shared Sub Main(ByVal args() As String) Console.WriteLine("Test is loaded.") File.Create("test.txt") End Sub 'Main End Class 'Program End Namespace
using System; using System.Security.Permissions; using System.IO; [assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted=true)] namespace Test { class Program { static void Main(string[] args) { Console.WriteLine("Test is loaded."); File.Create("test.txt"); } } }
サンドボックス アプリケーションを実行します。テスト アプリケーションが読み込まれて実行されます。テスト アプリケーションが読み込まれると、次のメッセージと共に例外がスローされます。
Could not load file or assembly 'Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.Failed to grant minimum permission requests.(Exception from HRESULT: 0x80131417)":"Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"}.
行を削除するか、コメント アウトして、RequestMinimum 要件を削除します。例が読み込まれて実行が開始されますが、次のメッセージと共に例外がスローされます。
Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
RequestMinimum フラグを使用することにより、失敗が明らかな場合にアプリケーションを読み込むのを避けることができます。アプリケーションをサンドボックス内で実行する方法の詳細については、「方法 : サンドボックスで部分信頼コードを実行する」を参照してください。
使用例
次の例では、LocalIntranet アクセス許可で実行されるサンドボックスを作成します。
Imports System
Imports System.Collections
Imports System.Diagnostics
Imports System.Security
Imports System.Security.Permissions
Imports System.Security.Policy
Imports System.Reflection
Imports System.IO
Class Program
Shared Sub Main(ByVal args() As String)
' Create the permission set to grant to other assemblies.
' In this case we are granting the permissions found in the LocalIntranet zone.
Dim e As New Evidence()
e.AddHostEvidence(New Zone(SecurityZone.Intranet))
Dim pset As PermissionSet = SecurityManager.GetStandardSandbox(e)
' Optionally you can create your own permission set by explicitly adding permissions.
' PermissionSet pset = new PermissionSet(PermissionState.None);
' pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
' pset.AddPermission(new UIPermission(PermissionState.Unrestricted));
Dim ads As New AppDomainSetup()
' Identify the folder to use for the sandbox.
ads.ApplicationBase = "C:\Sandbox"
' Copy the application to be executed to the sandbox.
File.Copy("..\..\..\HelloWorld\Bin\Debug\HelloWorld.exe", "C:\sandbox\HelloWorld.exe", True)
Dim hostEvidence As New Evidence()
' Commenting out the following statement has no effect on the sample.
' The grant set is determined by the grantSet parameter, not the evidence
' for the assembly. However, the evidence can be used for other reasons,
' for example, isolated storage.
hostEvidence.AddHostEvidence(New Zone(SecurityZone.Intranet))
' Create the sandboxed domain.
' You can replace the null parameter with a strong name that identifies full trust assemblies:
' GetStrongName(Assembly.GetExecutingAssembly())); This identifies any assemblies in the folder
' that are signed with the same strong name as this assembly as being full trust assemblies.
Dim sandbox As AppDomain = AppDomain.CreateDomain("Sandboxed Domain", hostEvidence, ads, pset, Nothing)
sandbox.ExecuteAssemblyByName("HelloWorld")
End Sub 'Main
Public Shared Function GetStrongName(ByVal [assembly] As [Assembly]) As StrongName
If [assembly] Is Nothing Then
Throw New ArgumentNullException("assembly")
End If
Dim assemblyName As AssemblyName = [assembly].GetName()
Debug.Assert(Not (assemblyName Is Nothing), "Could not get assembly name")
' Get the public key blob.
Dim publicKey As Byte() = assemblyName.GetPublicKey()
If publicKey Is Nothing OrElse publicKey.Length = 0 Then
Throw New InvalidOperationException("Assembly is not strongly named")
End If
Dim keyBlob As New StrongNamePublicKeyBlob(publicKey)
' Return the strong name.
Return New StrongName(keyBlob, assemblyName.Name, assemblyName.Version)
End Function 'GetStrongName
End Class 'Program
using System;
using System.Collections;
using System.Diagnostics;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using System.Reflection;
using System.IO;
namespace SimpleSandboxing
{
class Program
{
static void Main(string[] args)
{
// Create the permission set to grant to other assemblies.
// In this case we are granting the permissions found in the LocalIntranet zone.
Evidence e = new Evidence();
e.AddHostEvidence(new Zone(SecurityZone.Intranet));
PermissionSet pset = SecurityManager.GetStandardSandbox(e);
// Optionally you can create your own permission set by explicitly adding permissions.
// PermissionSet pset = new PermissionSet(PermissionState.None);
// pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
// pset.AddPermission(new UIPermission(PermissionState.Unrestricted));
AppDomainSetup ads = new AppDomainSetup();
// Identify the folder to use for the sandbox.
ads.ApplicationBase = "C:\\Sandbox";
// Copy the application to be executed to the sandbox.
File.Copy("..\\..\\..\\HelloWorld\\Bin\\Debug\\HelloWorld.exe", "C:\\sandbox\\HelloWorld.exe", true);
Evidence hostEvidence = new Evidence();
// Commenting out the following statement has no effect on the sample.
// The grant set is determined by the grantSet parameter, not the evidence
// for the assembly. However, the evidence can be used for other reasons,
// for example, isolated storage.
hostEvidence.AddHostEvidence(new Zone(SecurityZone.Intranet));
// Create the sandboxed domain.
// You can replace the null parameter with a strong name that identifies full trust assemblies:
// GetStrongName(Assembly.GetExecutingAssembly())); This identifies any assemblies in the folder
// that are signed with the same strong name as this assembly as being full trust assemblies.
AppDomain sandbox = AppDomain.CreateDomain(
"Sandboxed Domain",
hostEvidence,
ads,
pset,
null); // Optionally: GetStrongName(Assembly.GetExecutingAssembly()));
sandbox.ExecuteAssemblyByName("HelloWorld");
}
public static StrongName GetStrongName(Assembly assembly)
{
if (assembly == null)
throw new ArgumentNullException("assembly");
AssemblyName assemblyName = assembly.GetName();
Debug.Assert(assemblyName != null, "Could not get assembly name");
// Get the public key blob.
byte[] publicKey = assemblyName.GetPublicKey();
if (publicKey == null || publicKey.Length == 0)
throw new InvalidOperationException("Assembly is not strongly named");
StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey);
// Return the strong name.
return new StrongName(keyBlob, assemblyName.Name, assemblyName.Version);
}
}
}