解説

インサイド .NET Framework [改訂版]

第10回 ロールベース・セキュリティ

吉松 史彰
2003/09/10 改訂(改訂前の記事はこちら
Page1 Page2 Page3 Page4

 本稿は、2003/03/13に公開された記事を、.NET Frameworkの新しいバージョンである「.NET Framework 1.1」に対応させ、全面的に加筆・修正を行った改訂版です。

はじめに

Back Issue
1
マネージ・コード/アセンブリ/モジュール
2 アセンブリのアイデンティティ
3 アセンブリのロード
4 アセンブリとバージョン管理
5 アセンブリのロードとセキュリティ
6 コード・アクセス・セキュリティ(その1)
7 コード・アクセス・セキュリティ(その2)
8 コード・アクセス・セキュリティ(その3)
9 コード・アクセス・セキュリティ(その4)

 前回まで4回をかけて、コード・アクセス・セキュリティを解説した。コード・アクセス・セキュリティは、.NET Frameworkが世の開発者と管理者に問う、プログラムに対するセキュリティの新しい形であることはご理解いただけたと思う。ただし、だからといってユーザーごとにアクセス制御を行い、操作を制限するセキュリティ機構が無意味になるわけではない。実際に、.NET Frameworkにもユーザーごとにセキュリティを制御する仕組みは存在する。今回はその仕組み、ロールベース・セキュリティを紹介する。

 なお、.NET FrameworkはWindows 98とWindows Me上でも動作するが、これらのOSにはWindows NT系列で使われているユーザー認証機構が搭載されていないため、今回の解説内容は基本的に適用できない。

ユーザーベースかロールベースか

 ところで、ユーザーに対してセキュリティを構成するのに、なぜ「ユーザーベース」セキュリティではないのだろうか。その理由は、このセキュリティ機構を、アクセスするユーザーの立場から見ているのではなく、アクセスされるアプリケーションの立場から見た上で使っている言葉だからだ。

 例えば、ファイル・サーバ上の共有フォルダにあるファイルへのアクセスを考えてみよう。1人1人のユーザーは、共有ファイルを1度に1つしか開かないかもしれないが、ファイルの側から見れば多数のユーザーがそのファイルにアクセスしているだろう。このときファイルに対してユーザーが行う操作は、主に次のように分類できる。

  • 内容の読み取り
  • 内容の書き込み
  • ファイルの削除
  • ファイルの属性変更

 このとき、1万人のユーザー1人1人に、「ユーザーAは読み取りしかできません」「ユーザーBは読み書きできます」「ユーザーCは何でもできます」「ユーザーDは読み取りすらできません」というような権限の指定を行うのは面倒だ(下図)。

図 「ユーザーベース」のアクセス権限指定
ユーザーごとにファイルへのアクセス権限を設定する。個々のファイルに対して、どのユーザーがどのような操作を可能か指定するのは非常に面倒である。

 この面倒を解消するために考えられた概念が「ロール」である。

 ロールの仕組みでは、アクセスを行うユーザーと、アクセスを制御したいファイルとの間に、ロールというクッションを設ける。そしてファイルは、「読み取り専用のロールに属しているから、削除はできない」「何でもOKのロールに属しているから、書き込み可能」などという具合に、ユーザーではなくロールに対してアクセス制御を行う。ユーザーは、直接ファイルからアクセスを許可してもらわずに、代わりに特定のロールに所属する。実際にユーザーがファイルにアクセスすると、ユーザー自身ではなく、そのユーザーが属しているロールがチェックされて、操作が行えるかどうかが決定される(下図)。

図 「ロールベース」の権限設定
ユーザーはロールに属し、ロールに対するアクセス権限をファイルに設定する。

 この仕組みでは、ファイルの側を管理する管理者・開発者は、あらかじめファイルに対する操作をいくつかのロールに分割して定義しておくだけでよい。ユーザーとロールとの関連は、それぞれのサイトで個別にシステム管理者が定義できる。そもそもこの方が、システムの実態をより正確に反映しているだろう。企業において、例えば山田さんが経理のシステムにアクセスして帳簿を操作できるのは、それが「山田さんだから」ではない。山田さんが「現在経理部に属しているから」である。実際、山田さんが異動で経理部を離れたら、もう山田さんは経理システムにはアクセスできない。つまり、経理システムにとって、相手が山田さんかどうかは重要ではない。重要なのは、相手が「経理部員かどうか」だ。このように、ユーザー1人1人ではなく、そのユーザーがある時点で持っている役割(ロール)をベースにアクセス制御を行うため、ロールベース・セキュリティと呼ばれるわけだ。

 Windows上では、古くからロールベース・セキュリティの概念が実装されている。Windows NT系列のOSに存在する「ローカル・グループ」が、Windowsにおけるロールだ。ローカル・グループというロールは、主にシステムに対する特権操作と、ファイル・システムのアクセス制御に利用されている。またSQL Serverでも、データを読み取る、データを書き込む、管理操作を行うなどの権限を持つロールを定義できる。Windows NT上のMicrosoft Transaction Server(MTS)やWindows 2000上のCOM+にも、ロールベース・セキュリティが実装されている。

アイデンティティ

 .NET Frameworkにおいては、「ユーザー」という言葉は厳密な場面では使われない。ユーザーというとどうしても人間を連想してしまうが、プログラムを実行するのは人間とは限らないからだ。XML Webサービスなどはまさに、プログラムがプログラムにアクセスする例である。そこで、ユーザーの代わりに、.NET Frameworkでは「アイデンティティ」という言葉を使う。実際に、.NET Framework上で稼働するプログラムにとって、ユーザーとはSystem.Security.Principal.IIdentityインターフェイスを実装するオブジェクトとして表現される。このインターフェイスには、次のプロパティが定義されている。

プロパティ 内容
AuthenticationType このアイデンティティを「正当」であると見なしたときに使われた認証機構の種類。NTLMやKerberos、Passportなどが考えられる
IsAuthenticated このアイデンティティが、ある種の認証機構によって認証を受けたかどうかを表すブール値
Name このアイデンティティの名前
表 System.Security.Principal.IIdentityインターフェイスのプロパティ
.NET Framework上で稼働するプログラムにとって、ユーザーはIIdentityインターフェイスを実装するオブジェクトとして表現される。

 このインターフェイスを実装するクラスが、.NET Framework上にはあらかじめ4種類定義されている。もっとも、IIdentityは単なるインターフェイスであるため、システムに独自のアイデンティティ・オブジェクトを作ることも可能だ。

・System.Web.Security.FormsIdentity
 ASP.NETのフォーム認証を通過したアイデンティティを表す。

・System.Security.Principal.WindowsIdentity
 Windowsの認証を通過したアイデンティティを表す。例えばASP.NETのWebアプリケーションであれば、IISの認証を通過したWindowsユーザー(またはIUSR_Machineなどの匿名ユーザー)になる。Windowsアプリケーションであれば、そのアプリケーションを起動したWindowsユーザーになる。

・System.Web.Security.PassportIdentity
 ASP.NETでPassport認証を通過したアイデンティティを表す。

・System.Security.Principal.GenericIdentity
 特にどの認証機構にも結合されていない、プログラムから自由に制御できるアイデンティティを表す。

 これらのアイデンティティは、ほとんどの場合、何らかの認証機構を通過しているものであることに注意してほしい。つまり、.NET Framework上でのアイデンティティとは、認証を行ったあとに作られるオブジェクトである。認証を行った上で、例えばファイルに対する書き込みアクセスや、銀行口座への振込みなどの操作に対するアクセス制御を行うために使われるのがアイデンティティであり、ロールベース・セキュリティの機能である。セキュリティと一口にいうと、認証とアクセス制御(承認)を混同してしまうかもしれないが、ロールベース・セキュリティにおいては、認証はすでに行われたものとして、考慮の対象になっていない。

プリンシパル

 IIdentityのインターフェイスを見て疑問を持った読者も多いだろう。IIdentityにはロールに関する情報が一切含まれない。IIdentityはいわば「ユーザー」であり、ユーザーとロールを結び付けるにはまた別のオブジェクトが必要とされる。.NET Framework上では、System.Security.Principal.IPrincipalインターフェイスを実装するオブジェクトが、ユーザーとロールを結びつける役割を持っている。IPrincipalには次のようなメンバが定義されている。なお、プリンシパルとは「主体」という意味である。

メンバ 内容
Identityプロパティ このプリンシパルが指しているアイデンティティ
IsInRoleメソッド このプリンシパルが、引数に指定されたロールに属しているかどうかをブール値で返す
表 System.Security.Principal.IPrincipalインターフェイスのメンバ
.NET Framework上では、IPrincipalインターフェイスを実装するオブジェクトが、ユーザーとロールを結びつける役割を持っている。

 一見して分かるとおり、IPrincipalインターフェイスは、まさにアイデンティティとロールとを結び付けるためだけに存在する。このインターフェイスを実装するオブジェクトは.NET Framework上にあらかじめ2種類定義されている。IIdentityと同様に、IPrincipalを実装する独自のオブジェクトを作成することも可能だ。

・System.Security.Principal.WindowsPrincipal
 Windowsの認証を受けたアイデンティティと、そのアイデンティティが属するロール(Windowsのグループ)を持つ。

・System.Security.Principal.GenericPrincipal
 開発者が自由に定義できる、アイデンティティとロールとの組み合わせを表す。

 .NET Frameworkのロールベース・セキュリティとは、これらのプリンシパルに対してIsInRoleメソッドを呼び出し、返されたtrue/falseの値に従ってアクセスを制御する仕組みにほかならない。また、IPrincipalインターフェイスのIsInRoleメソッドが次のように定義されていることからも分かるとおり、.NET Framework上ではロールとは単なる文字列にすぎない。

bool IsInRole(string role);

 プリンシパルとアイデンティティを分けているのは、ロールベース・セキュリティを実現するためだ。同じユーザー(アイデンティティが同じ)でも、アクセスするリソースによって違うロールが与えられているはずだ。SQL Serverの場合なら、あるユーザーが、Northwindデータベースに対してはdbdatawriterのロールを持っているのに、masterデータベースに対しては、何の役割も持っていないということがあり得る。だから、アイデンティティにはロール情報を持たせられない。そこで、アイデンティティとリソースをマッチングさせたときに、そのアイデンティティが持つロールを結び付けて、プリンシパルとして管理するわけだ。プリンシパルは、実行時にリソースにアクセスしたときに初めて決定する。


 INDEX
  解説 インサイド .NET Framework [改訂版]
  第10回 ロールベース・セキュリティ
  1.アイデンティティとプリンシパル
    2.ロールベース・セキュリティの適用
    3.Webアプリケーションとロールベース・セキュリティ
    4.WebアプリケーションとNTFSアクセス制御
 
インデックス・ページヘ  「解説:インサイド .NET Framework [改訂版]」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間