連載

アプリケーション・アーキテクチャ設計入門
―― Application Architecture for .NETに学ぶ.NETシステム設計 ――

第4回 セキュリティ、運用管理、および通信のポリシーとその設計

日本ユニシス 猪股 健太郎
2003/12/20
Page1 Page2 Page3 Page4


Back Issue
1
.NET開発者のための設計ガイドライン
2
論理アーキテクチャを構成するコンポーネントの設計(プレゼンテーション層編)
3
論理アーキテクチャを構成するコンポーネントの設計(ビジネス/データ層編)

はじめに

 Application Architecture for .NET第3章は「セキュリティ、運用管理、および通信のポリシー」というタイトルである。この章に書かれているのは、「セキュリティ、運用管理、および通信のポリシーがすでに定められている場合において、それらを正しく実装するためにはアプリケーションおよびサービスをどのように設計すればよいか」だけである。組織的なポリシーの策定方法や、ポリシーの変更を動的にアプリケーションに反映させる方法などについては、このドキュメントの対象外であることに注意してほしい。

 ポリシーそのものは論理層(レイヤ)や物理層(ティア)とは独立して存在する。しかし、ポリシーを実装することは、各論理層(レイヤ)および物理層(ティア)の設計に大きく関連することである。従って第3章は、「論理層(レイヤ)から独立したソフトウェア部品を設計・実装する」ことだけでなく、「第2章で説明されているコンポーネントそれぞれで各種ポリシーを設計・実装する」ことにも重点を置いている。

 さて、前置きはこのくらいにして、さっそく第3章の内容を見ていこう。

セキュリティ・ポリシー

 最初に、セキュリティの一般原則がまとめられている。

  • 実証されたセキュリティ機構を利用し、独自のセキュリティ機構を実装するのは避けよ

  • 外部からの入力は信用するな

  • 外部サービスは安全でないと思え

  • 最小特権の原則を守れ。つまり、システム上のおのおのの処理に対しては、実行に必要な最低限の特権だけを与えるべきである

  • システムの境界面を減らせ

  • 何も設定しない場合はデフォルトで安全な動作をするようにしろ

  • STRIDE脅威モデルに従え。STRIDEとは、なりすまし(Spoofing Identity)、データの改ざん(Tampering with Data)、否認(Repudiability)、情報の暴露(Information Disclosure)、サービス拒否(Denial of Service)、特権の昇格(Elevation of Privilege)の頭文字を取ったものである。詳細はMSDNの「セキュリティ性を考慮したデザイン」を参照のこと

 以上の原則を踏まえたうえでセキュリティ対策を行う。これらはごくごく当たり前のことをいっているだけにすぎないが、無視するとアプリケーションやサービスの脆弱性に直結するので注意しなくてはならない。

 セキュリティ・ポリシーには、(1)認証、(2)承認、(3)安全な通信、(4)プロファイル管理、そして(5)監査が関連している。

(1)認証

 認証は、アプリケーションやサービスの利用者を安全に同定する機構だ。認証の結果は、承認、監査、そしてプロファイル管理などから利用されるため、セキュリティ確保のためには認証は不可欠である。通常、正しいユーザーだけが提供可能なクレデンシャル(信用情報)を受け取り、認証に利用する。クレデンシャルにはパスワードが多く利用されるが、バイオメトリクス(生体情報)、スマートカード、公開鍵証明書などもクレデンシャルになり得る。

アプリケーションやサービスの利用者を同定する認証
認証はセキュリティ確保のために不可欠である。認証のための情報にはパスワードが多く利用されるが、バイオメトリクス(生体情報)、スマートカード、公開鍵証明書なども利用可能である。

 クレデンシャルが正当なものであることが確認されたら認証は成功である。ユーザーには認証済みの印であるセキュリティ・トークンが返され、以後ユーザーはセキュリティ・トークンを提示すれば認証を受ける必要はない。

 この節では、「認証情報の引き渡し」「外部サービスの呼び出し」「独自の認証機構」について説明した後、前々回および前回で解説した第2章で示されているコンポーネント群をどのように設計・実装するかがまとめられている。

●認証情報の引き渡し

 理想としては、ビジネス・ロジックは認証の仕組みと分離されているべきである。例えば、ユーザー情報は認証や監査のためだけに必要で、ビジネス上の機能では必要ないのだったら、コンポーネントのメソッドにユーザー情報のパラメータを追加するのは避けた方がよい。

 とはいっても、認証や監査のためには、物理層(ティア)をまたがったコンポーネントの間で何らかの方法により認証情報を引き渡す必要がある。その際は、通信機構が持つ仕組みを利用してセキュリティ・コンテキスト(現在有効なセキュリティに関する属性)をやりとりすることができる。

  • 呼び出し元と呼び出し先が認証機構をまったく共有していないのであれば、セキュリティ・コンテキストを渡すことができない。その際は適切なクレデンシャルを渡すことで再認証が行われなければならない

  • 呼び出し元と呼び出し先が信頼関係にあるWindowsドメインに所属している場合か、呼び出し先がWindowsのアカウントに基づいて承認を行っている場合であれば、NTLM(NT LanMan)認証のトークンやKerberos認証のチケットを引き渡す通信機構、すなわちDCOM-RPCを利用できる。ただし、NTLMトークンは複数の物理層(ティア)をまたがっての利用はできないし、Kerberos認証の権限委譲にはポリシー・ファイルの設定が必要となる

  • 呼び出し元と呼び出し先がWindows以外の認証機構を共有しているのであれば、認証機構から受け取ったトークンを引き渡す必要がある。その際は、パラメータにトークンを追加するのではなく、SOAPヘッダのような「範囲外」の機構を使うべきである。ただしこのトークンは呼び出し元のコンピュータに関する情報は何も含んでいないことに注意する。このような機構は、長期にわたって存在するビジネス・トランザクションでの認証で利用されることが多い

  • 呼び出し元と呼び出し先が同一のアプリケーション・コンテキストで動作しているのであれば、Threadクラス(System.Threading名前空間)のCurrentPrincipalプロパティを利用できる

異なる物理層(ティア)のコンポーネント間での認証情報の引き渡し
呼び出し元と呼び出し先が認証機構を共有しているならば、セキュリティ・コンテキストやメッセージなどを引き渡すことができる。

●外部サービスの呼び出し

 アプリケーションが、その内部で外部サービスを呼び出している場合、一般的には、アプリケーション全体で共有する専用のアカウント(サービス・アカウントと呼ぶ)を用いて外部サービスを利用するのがよい。もしも個別ユーザーの権限で外部サービスを呼び出すのであれば、アプリケーションのユーザー情報と外部サービスのユーザー情報を対応付けるという、複雑な処理を実装しなければいけないためである。IISの認証機構を利用してユーザーを偽装するのであれば実装は楽だが、この場合はASP.NETなどのサービスをSYSTEM権限で実行する必要があるため、通常は勧められない。

●独自の認証機構

 アプリケーションの要件を実現するには、プラットフォームが提供する認証機構やサード・パーティが提供する認証機構では不可能な場合もある。そのようなときはアプリケーション独自の認証機構を実装することになるだろう。その際は以下のガイドラインに従うべきである。

  • IIdentityインターフェイス(System.Security.Principal名前空間)を継承したオブジェクト(以下、Identityオブジェクト)で認証機構を実装する。コンストラクタは、初めて認証が行われる場合のためにクレデンシャルを引数に取るものと、すでに認証が済んでいる場合のためにセキュリティ・トークンを引数に取るものの両方を実装する

  • パスワードはそのまま保存しない。クレデンシャルにソルト(ランダム性を加えるための値)を加えたもののハッシュ値を保存しておく

  • 認証失敗を監査する

  • 自分のアセンブリだけがIdentityオブジェクトを生成・利用できるようにするためにStrongNameIdentityPermission属性を使う

  • セキュリティ・トークンをIdentityオブジェクトのプロパティとして公開する。セキュリティ・トークンはユーザーIDに何らかのデータを追加したもののハッシュ値にする。追加するデータとしては、コンピュータ名やタイムスタンプなどが考えられる

●各コンポーネントにおける認証の設計と実装

−プレゼンテーション層−

 Webベースのユーザー・インターフェイス・コンポーネントで認証を実装するのであれば、MSDNの「ASP.NETにおける認証」を参照のこと。

 Windowsベースのユーザー・インターフェイス・コンポーネントでは、独自の認証機構を利用するか、Windowsのログオン・アカウントを利用するかのどちらかとなる。独自の認証機構を利用する場合、IPrincipalインターフェイス(System.Security.Principal名前空間)を継承したクラス(以下、Principalオブジェクト)を現在のスレッドに設定すること。

 ユーザー・プロセス・コンポーネントはユーザー・インターフェイス・コンポーネントと同じアプリケーション・コンテキストで動作するので、認証は実装しない。

−ビジネス層−

 ビジネス・コンポーネントは認証を行うか、サービス・インターフェイスの認証情報を引き継ぐ。呼び出し元のアイデンティティは、特定のユーザーだったり、サービス・アカウントだったり、特定のサービス・アカウントを利用する外部パートナーであったりする。もしもビジネス・コンポーネントが呼び出し元を認証するのであれば、以上の3種類のアイデンティティがどのように認証され、承認に影響を及ぼすのかを検討しなければならない。

 ビジネス・エンティティ・コンポーネントでは、ほかのアプリケーションやスクリプトで利用するのでなければ、現在のアプリケーション・コンテキストを利用できる。もしもビジネス・エンティティ・コンポーネントをほかのアプリケーションやスクリプトで利用できるようにするのなら、利用者が「ログオン」してセキュリティ情報を設定するのを手助けするコンポーネントが必要になるかもしれない。

−データ層−

 データ層のコンポーネント、すなわちデータ・アクセス・ロジック・コンポーネントおよびサービス・エージェントはアプリケーションやサービスのほかのコンポーネントから呼び出されるだけであり、スクリプトや別のアプリケーションなどから呼び出されることはない。従って現在のアプリケーション・コンテキストを利用できる。

 データ層のコンポーネントがデータベースや外部サービスを利用するときは、サービス・アカウントを利用する方法と、呼び出し元のユーザーを偽装する方法の2通りが考えられる。

 サービス・アカウントを利用するのは以下のような場合である。

  • ユーザーを偽装できない場合

  • アカウントを変えても呼び出し先の権限に大きな違いがない場合

  • 呼び出し先がアプリケーションと異なる認証機構を持つ場合

  • 複数のアカウントを使い分けるとコネクション・プーリングがうまく働かず、パフォーマンスに悪影響を与える場合

 ユーザーを偽装するのは以下のような場合である。

  • サービス・アカウントのクレデンシャルを安全に保管できない場合

  • セキュリティ・ポリシーにより、データなどのリソースが特定ユーザーに対応付けられている場合

  • 呼び出し先での監査が個別ユーザー単位で行われている場合

 ユーザーの偽装には、プラットフォームの偽装機能か、シングル・サインオンのソリューションを利用する。


 INDEX
  [連載] アプリケーション・アーキテクチャ設計入門
  第4回 セキュリティ、運用管理、および通信のポリシーとその設計
  1.セキュリティ・ポリシーに関する設計:認証
    2.セキュリティ・ポリシーに関する設計:承認、安全な通信、プロファイル管理、監査
    3.運用管理ポリシーに関する設計
    4.通信ポリシーにおける非同期通信と同期通信
 
インデックス・ページヘ  「アプリケーション・アーキテクチャ設計入門」


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 記事ランキング

本日 月間