次の方法で共有


認証と承認

Mary Kirtland
Microsoft Corporation

2001 年 2 月 28 日

先週のコラム では、Web サービスに対して考えられるライセンシング モデルと、サンプルの Favorites サービスに対して私たちが選んだライセンシング モデルについてお話しました。対象顧客は、自社のアプリケーションから Favorites サービスを使うことを考えている開発組織に設定しました。また、ユーザーのプライバシーの観点から、実際には顧客ごとに専用のデータ ストアを持ってもらうことにしました。顧客がそのデータ ストアへアクセスするときに、何らかの識別情報を指定します。識別情報はデータ ストアに関するものではなく、顧客に関するものにしました。つまり、Favorites へのアクセスを、サブスクリプションを申し込んだ顧客に限定するということです。

本稿では、Web サービスへのアクセスを限定するのに使用できる機構について重点的に述べます。まず利用可能な選択肢から見てみます。次に、選択肢の中で Favorites サービスに最も適しているのはどれかを分析します。最後に、Favorites のために私たちが実装したセキュリティ サブシステムの設計について論じます。

コメントに対するフィードバック

この連載コラムの「構想定義」の回を読んで、大変興味深いコメントをお寄せくださった方がいらっしゃいます。私は「ユーザーのプライバシー保護」の回で、そのコメントにお答えしようと思いながら、すっかり忘れていました。そこで今回、匿名の読者からのそのコメントをご紹介します。

「このサービス モデルには大きな問題がいくつかあり、プライバシーがその 1 つであることは明らかです。もう 1 つ私が取り上げてもらいたいのは、サービスまたは情報の提供者が、一般的に Web に掲載される情報に結び付けられている免責事項をどのように提示するかという問題です。たとえば、私は theweatherchannel.com によるコンテンツ配信をサービスとしてぜひ受けたいと思います。しかし、エンド ユーザーが、そのサービスを利用するシステム インテグレータから受け取った theweatherchannel.com のデータが間違っていた場合、責任はどちらにあるのでしょう。」

最初に私が考えたのは、免責事項や責任の配分はライセンス契約に組み込まれるべきだということです。皆さんの Web サービスにアクセスするために、顧客にアカウントを取得してもらうようにする場合は、免責事項やプライバシー ポリシーなどをライセンス契約に組み込み、顧客がアカウントを作成した段階でそれに同意したことにするようにできます。顧客にアカウントを取得するよう求めない場合は、ホームページの一番下に小さなフォントで「使用条件」のリンクを配置している Web サイトと同じことになります。ドキュメントを読んでも読まなくても、顧客はサイトを使った段階で使用条件に同意したことになります。同じことが、Web サービスとその直接の顧客にも当てはまると思います。

Web サービスのために掲示した利用上の注意やプライバシー ポリシーなどを直接または間接のクライアントに通知する方法に関しては、Web サービスのプロバイダや消費者が守るべき何かよい慣習がないか、現在、Microsoft 内の関係者と検討しています。何かよい案がみつかれば皆さんにお知らせします。

先週のコラムに対して、私たちのライセンシング メカニズムは何故このように複雑なのかお尋ねになり、「簡単にこの問題を解決できるずっとよい方法がある」というコメントをお寄せくださった方がいらっしゃいます。残念ながら、この方は匿名でコメントをお寄せになり、そのよい方法がどういうものかは書いてありませんでした。匿名さん、あなたのご意見をお待ちしています。改善の余地やもっとよい方法があるならお知らせください。もし本当に私たちの設計を改善できるとお考えならば、その方法を教えてください。現在、Favorites サービスは作業が進行中ですので、皆さんのご意見をどんどん採用したいと考えています。読者のコメントのほかに、私たちのニュースグループ で議論の口火を切ることもできます。またプライベートな議論をお好みの方は、wsgmsdn@microsoft.com まで電子メールをお寄せください。

セキュリティの概論

まず用語の定義から始めましょう。セキュリティには、たとえば、認証、承認、監査、データ プライバシー、データ整合性、可用性、否認防止などたくさんの問題があります。本稿では、認証承認を中心に論じます。(その他の問題についてもっと知りたい方は、Designing Secure Web-Based Applications for Microsoft Windows 2000 をお読みください。)

認証とは、誰か(または何か)が、本人の主張しているとおりの人物(または物)かどうかを確認する手続きです。この誰か、または何かのことをプリンシパルといいます。認証には認証資格情報と呼ばれる証拠が必要です。たとえば、クライアント アプリケーションから認証資格情報としてパスワードを提示してもらって、それが正しければクライアント アプリケーションは自身が主張している本人であると考えられます。

もちろん認証資格情報が盗まれたら、元も子もありません。認証手続きでは、偽装者が他人の認証資格情報を提示していることを見抜くことができません。認証資格情報の中には拇印のように偽造するのが難しいものもあれば、パスワードのように偽造しやすいものもあります。このため、セキュアな Web サービスを設計する上で考慮すべき重要事項は、受け付ける認証資格情報の種類を決定することです。

プリンシパルの身元が認証されたら、承認を与えるかどうかの決定が行われます。プリンシパルに関する情報と、アクセス コントロール リスト(ACL)のような情報と突き合わせて確認することにより、アクセス権が決定されます。クライアントごとに異なる等級のアクセス権を与えることができます。たとえば、あるクライアントには Web サービスへの全面的なアクセス権を与え、他のクライアントには一定の操作のアクセス権だけを与えることができます。また、あるクライアントにはすべてのデータへの完全アクセス権を与え、別のクライアントにはデータのサブセットへのアクセスのみを許可し、また別のクライアントには読み取りアクセス権を与えることができます。

認証と承認の選択肢

SOAP 仕様では、セキュリティについてはまったく触れられていません。最近リリースされた SOAP Security Extensions: Digital Signatures specification のように、一部で SOAP メッセージをセキュアにする方法に関する補助仕様を決定する作業が進められています。しかし、デジタル署名だけでは完全な認証方法とは言えません。したがって、SOAP のセキュリティ拡張についてはまだ課題が残っています。

SOAP メッセージをセキュアにする標準がなくても、他の Web アプリケーションをセキュアにするために使うのと同じ手法を使うことができます。この手法は、システム レベル、サード パーティ、アプリケーション レベルの 3 つの基本カテゴリに分類されます。

システム レベルの手法

システム レベルの手法は、オペレーティング システムのサービスを使って認証と承認を行います。Microsoft Windows® 2000 は、システム レベルの認証方法をいくつかサポートしています。

Web サービスへアクセスする必要があるコンピュータが正確にわかっている場合は、Internet Protocol Security(IPSec)ポート フィルタリング ポリシーやファイアウォール規則を使って、IP アドレスがわかっているコンピュータだけにアクセスを限定できます。プライベート ネットワーク内のコンピュータだけにアクセスを限定したいといった場合はこの手法が特に役に立ちます。IPSec は Web サービスやクライアント アプリケーションに変更を加えずに、ネットワーク レベルの認証、データ整合性、暗号化の機能を与えることができます。IPSec については、Microsoft Windows 2000 Server対応IPセキュリティ(IP Security for Microsoft Windows 2000 Server) を参照してください。

しかし、大抵のインターネット シナリオの場合は、すべてのクライアントの IP アドレスはわかりません。この場合、認証を実装する簡単な方法は、メッセージを交換するために使うプロトコルの認証機能を強化することです。大抵の Web サービスの場合は、HTTP 用に使える認証機能を強化することになります。Microsoft Internet Information Server 5.0(IIS)は、次の表に示すように、HTTP 用の認証機構をいくつかサポートしています。

基本認証 復号が容易な base64 でコード化されたテキストとしてユーザー名やパスワードが送信されるため、セキュアでない、または完全にセキュアでないクライアントの識別に使用します。認証資格情報が有効なユーザー アカウントと一致すれば、IIS によって Web サービスへのアクセスが許可されます。
SSL 基本認証 基本認証と同じですが、通信チャネルが暗号化されるため、ユーザー名とパスワードが保護されます。インターネットでの利用を考えている場合にはよい選択肢ですが、パフォーマンスに大きく影響します。
ダイジェスト認証 ハッシュ処理を行ってクライアントの認証資格情報をセキュアな方法で送信します。ただし Web サービス クライアントの開発ツールが幅広くサポートしているわけではありません。認証資格情報が有効なユーザー アカウントと一致すれば、IIS によって Web サービスへのアクセスが許可されます。
統合 Windows 認証 イントラネットでの利用のみを考えている場合に役立ちます。NTLM か Kerberos を使います。プロキシ サーバーや他のファイアウォール経由では使用できません。認証資格情報が有効なユーザー アカウントと一致すれば、IIS によって Web サービスへのアクセスが許可されます。
SSL 経由のクライアント証明書 各クライアントが証明書を取得する必要があります。証明書はユーザー アカウントにマップされ、IIS によって Web サービスへのアクセスを許可するために使用されます。インターネットでの利用を考えている場合には捨てがたい選択肢ですが、現在のところデジタル証明書の使用は普及していません。Web サービス クライアントの開発ツールが幅広くサポートしているわけではありません。SSL 接続経由でしか使えないため、パフォーマンスが問題となります。

これらの認証機構の詳細については、TechNet の IIS 4.0 and 5.0 Authentication Methods Chart を参照してください。

Web サービス実装者の観点からいうと、これらの認証機構を使う利点の 1 つは、Web サービスでコードを変更する必要がない点です。IIS がすべての認証と ACL 承認の確認を行ってから、Web サービスが呼び出されます。ただし、少し設定作業を行う必要があります。特に、Web サービスへのアクセスを許可したクライアントそれぞれに Windows 2000 のアカウントを作成し、Web サービスを構成するリソースに対して適切な ACL を設定する必要があります。

ただし、これらの認証機構の 1 つを選択する前に、クライアント アプリケーションの機能を考慮する必要があります。クライアント アプリケーションは、サーバーからの認証資格情報のリクエストに応答する必要があります。Web サービス クライアントの開発ツールでこれを自動的に処理できるのが理想ですが、すべてのツールがすべての認証機構をサポートしているわけではありません。ツールがサポートしていない場合は、クライアント アプリケーションの開発者は、認証資格情報のリクエストに応答するコードを実装する必要があります。本稿の最後に、Microsoft の開発ツールがサポートしている認証機構の一覧表があります。

サード パーティの手法

もう 1 つの方法は、サード パーティの認証サービスを利用することです。認証サービスを提供するさまざまな製品が市販されています。たとえば、Microsoft Passport は、Web アプリケーション開発者が顧客を認証するために使用できるサービスです。おそらく大抵の人にとっては、Passport といえば、アプリケーション、コンピュータ、企業ではなく、エンド ユーザーを認証する方法としておなじみでしょう。しかし、顧客がアプリケーションや企業を表すパスポートを取得しても何の差し支えもありません。

アプリケーション間の通信用認証機構として Passport を使うときの最大の障害は、開発ツールでのサポートが少ない点です。私たちが知る限りでは、Passport をサポートしている Web サービス開発ツールは、Microsoft .NET Framework の一部である ASP.NET だけです。しかし、ASP.NET にも、クライアント アプリケーションから Web サービスへ Passport の認証資格情報を送信する機能がありません。各クライアント アプリケーション側で独自のコードを実装する必要があるでしょう。

たとえ将来、ツールによるサポートが増えたとしても、今現在には何の役にも立ちません。Passport や他のサード パーティの認証サービスを使って Web サービスへのアクセスを限定する場合は、クライアント アプリケーション開発者が自分のアプリケーションがサービスへ接続できるようにするために、もう少し多くの作業が必要になることを覚悟してください。

アプリケーション レベルの手法

システム レベルおよびサード パーティの手法の主な利点は、誰か他の人がコードを書いて、悪いユーザーがシステムを攻撃するために利用できるバグがないことを確認済みであることです。しかし、上記の手法がふさわしくない状況もあります。たとえば、ユーザーのアカウント情報のカスタム データベースを持っている場合などです。それぞれのユーザーごとに Windows のユーザー アカウントを作成する代わりに、既存のデータベースを使いたいかもしれません。または、アクセス確認がアプリケーションによって実行時にだけわかるデータに依存する場合などです。

これらの状況では、カスタム認証機構を実装することができます。たとえば、SOAP メッセージを送る場合に、クライアントの認証資格情報が SOAP メッセージそのもので送られるように Web サービス コントラクトを定義することができます。この方法の場合、メッセージから認証資格情報を取り出し、自分の承認論理を実装する必要がありますが、好みのクライアント アカウント データベースを使うことができます。SOAP メッセージでクライアントの認証資格情報を送る方法が 2 つあります。

  • SOAP ヘッダとして認証資格情報(ユーザー名とパスワード)を組み込みます

  • SOAP 本文の要素として認証資格情報を組み込みます

ただし、SOAP メッセージが XML であることを思い出してください。したがって、HTTP を使ってメッセージを送る場合、ユーザー名やパスワードは、悪意のあるユーザーが探しているものを知るにはお誂え向きな <username> や <password> などのタグが付いたクリア テキストで送られます。メッセージごとに HTTP の代わりに SSL を使えば、認証資格情報をクリア テキストで送らずに済みます。ただし、SSL は HTTP 単独よりもはるかに遅いので、セキュリティとパフォーマンスの長短を慎重に考える必要があります。

事前に計画して、Web サービスで提供されるいくつかの操作に SSL を使い、セキュリティがあまり問題とならないオペレーション用にもっと軽量の手法を使うことができます。たとえば、SOAP RPC 規約を使って、SOAP 本文の要素として認証資格情報を受け付け、セッション キーを返す特別な「ログオン」操作を Web サービス用に定義できます。ログオン メソッドだけを SSL 経由で送ればよいのです。その他のメッセージは、セッション キーを SOAP ヘッダか SOAP 本文に組み込んで、HTTP 経由で送ることができるでしょう。この方法だと、セッション キーが盗まれる危険がありますが、クライアントのパスワードが盗まれる危険は低くなります。

ASP.NET は、HTTP のクッキーに基づく別のアプリケーション レベルの認証機構をサポートしています。この手法は、セッション キーを SOAP メッセージではなく、クッキーに入れて送ります。ASP.NET は、ユーザー データベースと比較して認証資格情報を検査し、セッション キーを生成するインフラまたは着信リクエストに応じてセッション キーを解釈するサポートを提供します。詳細については、.NET Framework SDKドキュメント documentation(.NET Framework SDK documentation) を参照してください。

Favorites のセキュリティ モデルの選択

私たちは Favorites サービスのためにセキュリティを実装する方法を考え始めたとき、認証と承認に関する 5 つの主な基準を決定しました。

  1. 顧客のパスワードはクリア テキストとして送信してはなりません。

  2. ユーザーのお気に入りデータはクリア テキストとして送信しても構いません。

  3. 顧客のユーザー名とパスワードが盗まれないと仮定した場合、顧客の認証資格情報を偽造することは極めて困難であり、誰もそんなことを試みようとはしないでしょう。

  4. 私たちが Web サービスを実装するために選択する開発者ツールを使って、選択した認証機構を実装するのは容易に違いありません。たとえば、SOAP メッセージの構文を解析し、リクエストをコンポーネント メソッドへディスパッチするためのコードを書く必要はないでしょう。

  5. さまざまな開発者ツールを使って、Web サービスへアクセスするクライアント アプリケーションを実装するのは容易に違いありません。たとえば、クライアント アプリケーションは SOAP メッセージを構成し、または HTTP メッセージを送受信するためのコードを実装する必要はないでしょう。

Web サービスをつくるときの実装しやすさの問題を除いて、これらはすべて私たちの機能仕様(functional spec) に定めたセキュリティ ポリシーに盛り込まれています。(対象顧客が Favorites サービスをライセンスする開発組織であり、エンド ユーザーでないことを思い出してください)。

さらに、私たちはこれらの基準と比較して上記の手法をそれぞれ評価しました。

HTTP 経由の基本認証はパスワードをクリア テキストとして送信するので、私たちはこれを即座に除外しました。他方、各メソッドの呼び出しごとに SSL 経由で基本認証を使うのは行き過ぎに思われました。ユーザーのお気に入りデータがクリア テキストとして送信されるのはいいでしょう。 もし医療記録や財務記録を保存する場合は、恐らく私たちはこの手法の使用を真剣に考えたことでしょう。

ダイジェスト認証、統合 Windows 認証、またはクライアント証明書の使用は、一部のクライアントには問題となる場合があります。クライアントとサーバーのドメイン間の信頼関係に頼るわけにはいかないので、統合 Windows 認証を除外することができるでしょう。私たちが評価を行ったときには、Microsoft で使える主なツールセットは、SOAP Toolkit 1.0、ASP.NET Beta 1、および ATL Server でした。SOAP Toolkit 1.0 はダイジェスト認証をサポートしていません。また ASP.NET はクライアント証明書をサポートしていません。したがって、Microsoft 以外のツールをみなくても、ダイジェストもクライアント証明書も実行可能な選択肢とは思われませんでした。

Microsoft Passport の使用は、クライアントにもっと大きな困難を生じさせるでしょう。私たちが知っているツールのなかで、クライアント アプリケーション開発者が Passport の認証資格情報を Web サービスに送るのに役立つものはありません。それぞれのクライアントは、Passport SDK を使って、Passport のログオン プロトコルのサポートを実装する方法をみつける必要があるでしょう。私たちがどんなに Passport を認証機構として使いたいと思っても、私たちの基準を満たしませんでした(しかし、私たちは将来のサンプルで Passport を使うことを計画しています)。

こうして残ったのが、アプリケーション レベルの認証でした。私たちは顧客のパスワードをクリア テキストで送信したくなかったので、Favorites サービスがサポートする各操作にわずかなパラメータを追加するだけでは十分ではありませんでした。そこで、私たちは SSL 経由で呼び出され、ログオン キーを返す特別なログオン メソッドを実装することにしました。Favorites サービスによってサポートされる他のすべての操作を HTTP 経由で呼び出せるようにし、ログオン キーを最初のパラメータとして取るようにします。

もう 1 つの選択肢は、メソッド自身にパラメータを送るのではなく、ログオン メソッドに対して SSL 経由の基本認証を使う方法です。しかし、基本認証が Windows のユーザー アカウントを使うことを思い出してください。Web サービスが使うセキュアなリソースは、個別の統合セキュリティ記述子のないデータベース内のレコードです。したがって、あるレベルでは、IIS によって認証された Windows のユーザー アカウントと、私たちがデータベース内のアカウントを識別するのに使う機構との間で翻訳を行う必要があります。つまり、有効なアカウントのリストを 2 つ用意して、同期させる必要があるということです。ただし、1 つのアプリケーション固有のライセンシー アカウント データベースを使った、パラメータによる方法で十分うまくいきます。

Favorites へのセキュリティの実装

次の図は、Favorites サービスの認証および承認の仕組みを示したものです。

図 1 Favorites サービスの認証および承認設計

Favorites サービスの主な機能は、Account(ユーザーのお気に入り管理を扱う)と Report の 2 つの Web サービスで実装されています。ログオン リクエストの処理には、独立の Web サービスである Logon を実装しました。Microsoft では、Web サービスの実装に SOAP Toolkit 2.0 を使っているため、各 Web サービスは、受信したリクエストを、対応する COM クラスのメソッドにマップします。SOAP Toolkit 2.0 の場合、特定の Web サービスに対する SOAP リクエストはすべて 1 つの URL に転送されます。ログオン リクエストに対しては SSL を要求し、その他のすべての操作に対しては通常の HTTP リクエストを受け付ける必要があり、また IIS を通じて SSL を動作させられる最小単位が URL であるため、ログオン リクエストは独立の Web サービスで処理する必要があるのです。

クライアント アプリケーションで Favorites サービスを使う場合は、まず SSL を通じてログオン リクエストを Logon Web サービスへ送ります(1)。このリクエストは Logon COM オブジェクトの Logon メソッドへディスパッチされます(2)。Logon メソッドはユーザー名とパスワードを入力として受け取り、ハッシュ処理されたログオン キーを返します。これがクライアント アプリケーションへ返送されます(図では hashedKey で示されています)。

さらにクライアント アプリケーションは、hashedKeyAccountReport Web サービスへの各リクエストの第 1 パラメータとして送ります(7)。これらのリクエストは、対応する AccountReport COM オブジェクトのメソッドへディスパッチされます(8)。それぞれのメソッドは、hashedKey パラメータが有効なキーであることを確認し、そのキーに対応するライセンシー ID を取り出します(9)。キーが有効であれば、メソッドはそのまま作業を続けます。(この連載を毎回読んでいらっしゃる方のために補足すると、前回までの記事で Favorites Web サービスと呼んでいたものが、この Account Web サービスです。実際の実装では Account Web サービスと呼ぶことになるので、今からこの名前に慣れておいていただきたいと思います)。

この手法に潜在する問題点は、hashedKey が盗まれる危険性です。ライセンシーに属する hashedKey へアクセスできる人は誰でも、Favorites サービスを呼び出し、ライセンシーに関連付けられたデータにアクセスできます。このような攻撃にさらされる可能性を減らすために、ログオン キーは 60 分後に時間切れになります。ログオン キーの期限が切れると、クライアント アプリケーションは再びログオン リクエストを行い、新しいキーを取得する必要があります。有効期限は、セキュリティと可用性の間の妥協案として選ばれました。クライアント アプリケーションは、SSF_ERROR_INVALID_KEY エラーが SOAP 障害として返されるかどうかを監視することによって、キーが有効性を失ったことを検出できます。

ログオン リクエストを処理する必要のあるライセンシーに関する情報は、SSF-Logon データベースの LicenseePasswords テーブルに格納されています。このテーブルは、独立のデータベースに格納されている完全なライセンシー情報のサブセットです。SSF-Logon データベースにも Keys テーブルがあり、それはログオンキーをライセンシー ID にマップし、キーの有効期限を管理します。SSF-Logon データベースの負荷を軽減するために、Keys テーブルの部分はそれぞれ、Favorites サービスをホストする Web ファームの各 Web サーバーにキャッシュされます。KeyCache は Windows のサービスとして実装され、COM クラス Key を公開し、LogonAccountReport オブジェクトがこれを使ってハッシュ処理されたキーを計算し、検査します。私たちは定期的に期限切れのキーを Keys テーブルと KeyCache の両方から削除します。

Logon.Logon メソッドが呼び出される手順を見てみましょう。ログオンに関するビジネス ルールのほとんどは、実際には、Logon という名前の SSF-Logon データベースのストアド プロシージャに実装されています(3)。ストアド プロシージャ Logon の疑似コードは次のようになります。


  Procedure Logon([in]username, [in]password, [out]key, [out]licenseeID)
   Key = null, licenseeID = 0
   Locate record in LicenseePasswords with username, password (4)
   If not found,
      Return error SSF_ERROR_BAD_CREDENTIALS
   Else If license has expired,
      Return error SSF_ERROR_LICENSE_EXPIRED
   Else If license status is not Active,
      Return appropriate error
   Else
      Generate a new key
      Retrieve licenseeID from LicenseePasswords record
      Insert new record into Keys table
         with expiration set 60 minutes from now (5)
      If insert record failed,
         Return error SSF_ERROR_COULD_NOT_CREATE_KEY
End Procedure

これについては見ておわかりになると思いますので、2 点だけ指摘しておきます。まず、ライセンシーは同時に何度でもログオンできます。たとえば、クライアントが Web ファームにインストールされている場合、アプリケーションは Web ファームのそれぞれのマシンからログオンすることになるでしょう。また、ライセンシーが Favorites サービスを使う複数のアプリケーションをもっていれば、同じ licenseeID に対して Keys テーブル内に複数のレコードが存在することになるでしょう。

また、ストアド プロシージャによって生成されたキーは UUID です。Windows 2000 の場合、UUID から特定のマシンや MAC アドレスなどを割り出すことはできません。基本的に、これらは 128 ビットの無作為の数字です。したがって、これらのキーを推定するのは至難の業です。

ストアド プロシージャ Logon が返されると、Logon.Logon メソッドは引き続き Key オブジェクトを作成し、HashKey メソッドを呼び出します(6)。HashKey メソッドは Windows Cryptography API を使って、次の形式のハッシュ処理されたキーを計算します。


  UuidToString(key) &amp; Hex(Hash(key, secret))

Hash(key, secret) は暗号ハッシュを計算し、Hex(n) は 16 進法で n 桁の数字の文字列表現を計算します。Key.HashKey によって返された値は、クライアント アプリケーションに返されます。

次いで、Account または Report クラスのメソッドを呼び出す手順を見てみましょう。それぞれのメソッドは基本的に同じ構造をとります。


  Public Sub Method(ByVal hashedKey As String,・
   nErrorCode = 0
   Initialize an audit log object
   Verify hashedKey is a valid key &amp; retrieve the licenseeID (9)
   If valid,
      Validate method specific input parameters
      Do method specific work
      Update audit log object with result of work
   Else
      nErrorCode = SSF_ERROR_INVALID_KEY
   Save the audit log object
   If nErrorCode <> 0,
      ReportError nErrorCode
End Sub

SSF_ERROR_INVALID_KEY が返される理由についてはすでに説明しましたので、hashedKey を検査する方法について見てみましょう。いずれのクラスもヘルパ機能を使って、Key オブジェクトを作成し、Validate メソッドを呼び出します(9)。このメソッドはハッシュされたキーを入力として取り、キーが有効なら、対応するライセンシー ID を返します。0 の値が返されると、キーは有効ではありません。疑似コード形式の場合は、Validate は次のようになります。


  Public Function Validate(hashedKey as String) as Long
   Validate = 0
   Set key = original logon key substring at beginning of hashedKey
   If Hash(key, secret) = remainder of hashedKey,
      Look for record corresponding to key in KeyCache (10)
      If found,
         If key has not expired,
            Validate = licensee ID in KeyCache record
         Else
            Delete record from KeyCache
      Else
         Look for record in SSF-Logon.Keys table corresponding to
            key and not expired (11)
         If found,
            Add record to KeyCache (12)
            Validate = licensee ID in record found
End Function

まず、hashedKey が有効であるか検査します。有効であれば、KeyCache の中からキーを探します(10)。KeyCache の中に該当するキーがない場合のみ、データベースからキーを検索します(11)。

何故わざわざログオン時にキーをハッシュ処理し、メソッドを呼び出すたびにハッシュを検査するのか不思議に思うかもしれません。結局のところ、無作為に生成される UUID は、推測しにくいログオン キーになるようにみえます。しかし、アプリケーションが無効なキーでリクエストを出したらどうなるか考えてみてください。KeyCache の中でキーを探しても見つかりません。さらに、SSF-Logon.Keys テーブルでキーをクエリーすることになります。無効なキーでリクエストが送信されるたびに、データベースを調べることになります。無効なキーでたくさんのサービス リクエストを出すだけで、非常に簡単にサービス拒否攻撃を開始することができてしまいます。

クライアント アプリケーションに返すキーにオリジナルのログオン キーのハッシュを加えることによって、KeyCache やデータベースを調べなくとも、大抵の本当に無効なキーを除外できます。Validate 疑似コードに示したテストに合格するような hashedKey を推定するのは極めて困難でしょう。

これで私たちの認証および承認サブシステムの説明は終わりです。AccountReport 操作が呼び出されたときに、有効な認証資格情報が与えられると、呼び出し元のアプリケーションはその操作を実行する承認を得ます。しかし、ユーザーのお気に入りへのアクセスや、Key.Validate によって取り出されたライセンシー ID に関連付けられたデータのレポートしかできません。

結論

Web サービスへのアクセスの限定は、他の Web サイトへのアクセスの限定とあまり違いません。しかし、サービスを呼び出すクライアント アプリケーションは、ユーザー インターフェイスを表示してログオンの承認資格情報を取り出すことはできません。これらのクライアント アプリケーションの開発者は、サービスに送られたメッセージに必要な認証資格情報を入れることはできないでしょう。顧客が使う開発ツールによってサポートされた認証機構を使えば、承認されたクライアント アプリケーションは Web サービスへ最もアクセスしやすくなります。

Favorites サービスでの経験からいうと、クライアントの認証資格情報を SOAP リクエストの本文で送ることによって、アプリケーション レベルの認証および承認を実装するのが簡単です。多分、テストの時間を最大化するために、早い時期に認証および承認サブシステムを実装したいと思うでしょう。また、システムが悪意のあるものつけ込む隙がないかセキュリティの専門家にシステムを見てもらうべきです(先ほどサービス拒否攻撃の問題に触れたのも、皆さんの注意を喚起したいと思ったからです)。

もちろん、認証と承認は完全なセキュリティ ソリューションの一部にすぎません。Favorites サービスのセキュリティの全容については、サンプル コードをリリースする頃に改めて取り上げたいと思っております。それまでの間、Web サーバーをセキュアにする方法について詳しく知りたい方は、Internet Information Services 5.0 のドキュメントをご覧ください。Windows DNA 技術に基づき Web アプリケーションをセキュアにする方法を詳しく知りたい方には、MSPress の Designing Secure Web-Based Applications for Microsoft Windows 2000 を強くお奨めします。

次週は、Web サービスの要件の中で見落としがちなもの、すなわちサービスを使う Web アプリケーションの開発者、テスト担当者、運営要員についてお話します。こうした人たちがサービスを上手に使うにはどんなドキュメントやツールが必要なのでしょうか?要件を引き出すために皆さんが質問すべき項目、Favorites サービスに対して私たちが見つけ出した要件、それらの要件が私たちのプロジェクトに及ぼした影響について見ていきます。

Microsoft のツールによるサポート

次の表は、本稿で取り上げた認証機構に対する Microsoft のツールに組み込まれているサポート機能を示しています。クライアント側のサポートというのは、ツールによって生成されたプロキシが自動的に正しい HTTP メッセージを生成し、認証資格情報を Web サービスに送ることを意味しています。サーバー側のサポートというのは、ツールによって提供された Web サービスのリスナ インフラが、着信リクエストに応じて自動的に認証資格情報を認証することを意味しています。

認証機構に対するクライアント側のサポート

認証機構 ASP.NET (Beta 1) ATL Server (Beta 1) SOAP Toolkit 2.0 (Beta 2) SOAP Toolkit 1.0 (Dec 版)
基本認証 Yes Yes Yes Yes
SSL 経由の基本認証 Yes Yes Yes Yes
ダイジェスト認証 Yes Yes Yes No
統合 Windows 認証 Yes Yes Yes NTLM のみ
クライアント証明書 No Yes Yes Yes
Microsoft Passport No No No No
Cookie ベースの認証 Yes No No No

認証機構に対するサーバー側のサポート

認証機構 ASP.NET (Beta 1) ATL Server (Beta 1) SOAP Toolkit 2.0 (Beta 2) SOAP Toolkit 1.0 (Dec 版)
基本認証 Yes1 Yes1 Yes1 Yes1
SSL 経由の基本認証 Yes1 Yes1 Yes1 Yes1
ダイジェスト認証 Yes1 Yes1 Yes1 Yes1
統合 Windows 認証 Yes1 Yes1 Yes1 Yes1
クライアント証明書 Yes1 Yes1 Yes1 Yes1
Microsoft Passport Yes2 No No No
Cookie ベースの認証 Yes No No No

1. 認証は IIS によって行われます。ツールにはその他のサポートは必要ありません。

2. Microsoft Passport SDK がインストール済みであり、サービス プロバイダは Passport サイトの ID を取得していなければなりません。