解説
インサイド .NET Framework
第11回 コード・アクセス・セキュリティ(その3)
インフォテリア株式会社
吉松 史彰
2002/11/29
|
|
アクセス許可セット
メンバーシップ条件が一致してコード・グループが決定すると、そのコード・グループに割り当てられているアクセス許可セットが取得され、アセンブリに適用される。アクセス許可セットとは、文字どおりアクセス許可の集合だ。アクセス許可とは、アセンブリが操作を行うために必要な権限を表すオブジェクトだ。主にアプリケーションから外部のリソースに対するアクセスが必要になる操作に対して、関連するアクセス許可が定義されている。
例えば、FileReaderアセンブリで行っているように、外部のファイルというリソースにアクセスするためには、「ファイルにアクセスする」というアクセス許可が必要になる。.NET Frameworkでは、System.Security.Permissions.FileIOPermissionというクラスのオブジェクトとして、ファイル・アクセスに対するアクセス許可が定義されている。また、SQL Serverという外部のデータベース・リソースにアクセスするためには、「SQL Serverに接続する」というアクセス許可が必要になる。.NET Frameworkでは、System.Data.SqlClient.SqlClientPermissionというクラスのオブジェクトとして、SQL Serverに対するアクセス許可が定義されている。
例のごとく、上記サンプル・プログラム1のコードを若干変更して、FileReaderアセンブリのエビデンスから割り出されるコード・グループに、それぞれどんなアクセス許可セットが設定されているのか確認してみよう。次のコードの太字部分が上記からの変更個所である。
using System;
using System.Collections;
using System.Reflection;
using System.Security;
using System.Security.Policy;
class MainClass {
static void Main(string[] args) {
FileReader reader = new FileReader(args[0]);
Assembly asm = reader.GetType().Assembly;
IEnumerator itor = SecurityManager.PolicyHierarchy();
while(itor.MoveNext())
{
PolicyLevel pl = itor.Current as PolicyLevel;
Console.WriteLine("{0}:", pl.Label);
CodeGroup cg = pl.ResolveMatchingCodeGroups(asm.Evidence);
Recurse(cg, 1);
}
// Console.WriteLine(reader.ReadWhole());
}
static void Recurse(CodeGroup cg, int level)
{
for (int i = 0; i < level; i++)
Console.Write("\t");
Console.WriteLine("{0} ({1})",
cg.Name, cg.PermissionSetName);
foreach(CodeGroup child in cg.Children)
Recurse(child, level + 1);
}
}
|
|
FileReaderアセンブリのアクセス許可セットを表示するサンプル・プログラム2 |
ポリシーの階層ごとに、FileReaderアセンブリが属するコード・グループの名前とともに、そのコード・グループに設定されているアクセス許可セットも表示する(太字部分がサンプル・プログラム1からの変更部分)。 |
このコードを、.NET Frameworkのインストール直後の状態でC:\Tempから実行すると、次のような結果が得られる。
C:\TEMP>MainClass.exe C:\Boot.ini
Enterprise:
All_Code (FullTrust)
Machine:
All_Code (Nothing)
My_Computer_Zone (FullTrust)
User:
All_Code (FullTrust)
|
|
サンプル・プログラム2の実行結果 |
.NET Frameworkのインストール直後の状態で、C:\Tempからサンプル・プログラム2を実行した場合。 |
FullTrustとNothingという2つのアクセス許可セットがそれぞれ設定されていることが分かる。それでは、このアクセス許可セットはどんなアクセス許可の集合なのだろうか。次のコードを実行して確認してみよう。
using System;
using System.Collections;
using System.Reflection;
using System.Security;
using System.Security.Policy;
class MainClass {
static void Main(string[] args) {
FileReader reader = new FileReader(args[0]);
Assembly asm = reader.GetType().Assembly;
IEnumerator itor = SecurityManager.PolicyHierarchy();
while(itor.MoveNext())
{
PolicyLevel pl = itor.Current as PolicyLevel;
Console.WriteLine("{0}:", pl.Label);
CodeGroup cg = pl.ResolveMatchingCodeGroups(asm.Evidence);
Recurse(cg, 1);
}
// Console.WriteLine(reader.ReadWhole());
}
static void Recurse(CodeGroup cg, int level)
{
for (int i = 0; i < level; i++)
Console.Write("\t");
Console.WriteLine("{0} ({1})", cg.Name, cg.PermissionSetName);
PolicyStatement pol = cg.PolicyStatement;
if (pol != null)
{
PermissionSet ps = pol.PermissionSet;
IEnumerator itor = ps.GetEnumerator();
while(itor.MoveNext())
{
for (int i = 0; i < level + 1; i++)
Console.Write("\t");
Console.WriteLine("({0})",
((IPermission)itor.Current).GetType());
}
}
foreach(CodeGroup child in cg.Children)
Recurse(child, level + 1);
}
}
|
|
アクセス許可セットの内容を表示するサンプル・プログラム3 |
FileReaderアセンブリが属するコード・グループに設定されている各アクセス許可セットに含まれるアクセス許可(System.Security.CodeAccessPermissionクラスの派生クラスとして定義されている)を列挙する(太字部分がサンプル・プログラム2からの変更部分)。 |
このコードを、.NET Frameworkのインストール直後の状態でC:\Tempから実行すると、次のような結果が得られる。
C:\TEMP>MainClass.exe C:\Boot.ini
Enterprise:
All_Code (FullTrust)
Machine:
All_Code (Nothing)
My_Computer_Zone (FullTrust)
User:
All_Code (FullTrust)
|
|
サンプル・プログラム3の実行結果 |
.NET Frameworkのインストール直後の状態で、C:\Tempからサンプル・プログラム3を実行した場合。 |
この実行結果は、サンプル・プログラム2の結果と何も変わっていない。実は、FullTrustとNothingという2つのアクセス許可セットは、中身が何もないのだ。Nothingの方は文字どおり中身が何もないので、これが割り当てられたコード・グループに所属するアセンブリには、一切のアクセス許可が与えられないことを意味する。一方、FullTrustの方は特別なアクセス許可セットである。このアクセス許可セットがコード・グループに割り当てられているということは、そこに所属するアセンブリにはシステム上のすべてのアクセス許可が与えられていることを意味する。FullTrustは、中身は空でも非常に強力なアクセス許可セットなのだ。
前回解説した手順でFileReaderアセンブリのロード方法を変更して、ZoneエビデンスとしてIntranetを持つようにして上記のサンプル・プログラム3をもう一度実行すると、今度は次のような結果になる。
C:\TEMP>MainClass.exe C:\Boot.ini
Enterprise:
All_Code (FullTrust)
Machine:
All_Code (Nothing)
LocalIntranet_Zone (LocalIntranet)
(System.Security.Permissions.EnvironmentPermission)
(System.Security.Permissions.FileDialogPermission)
(System.Security.Permissions.IsolatedStorageFilePermission)
(System.Security.Permissions.ReflectionPermission)
(System.Security.Permissions.SecurityPermission)
(System.Security.Permissions.UIPermission)
(System.Net.DnsPermission)
(System.Drawing.Printing.PrintingPermission)
(System.Diagnostics.EventLogPermission)
Intranet_Same_Site_Access (同じサイトの Web です。)
Intranet_Same_Directory_Access (同じディレクトリ FileIO - Read, PathDiscovery)
User:
All_Code (FullTrust)
|
|
アセンブリのロード方法を変更した場合のサンプル・プログラム3の実行結果 |
ZoneエビデンスとしてIntranetを持つように、FileReaderアセンブリを共有フォルダからロードするようにして、サンプル・プログラム3を実行した場合。 |
エビデンスが変化したので、FileReaderアセンブリが所属するコード・グループがLocalIntranet_Zoneに変わり、その結果アクセス許可セットもLocalIntranetに変更されている。LocalIntranetというアクセス許可セットには、9つのアクセス許可が含まれていることが分かるだろう。
Insider.NET 記事ランキング
本日
月間