特集
次世代XML Webサービスを試す Part 2

2.セキュリティ・トークンと認証

インフォテリア株式会社
吉松 史彰
2003/01/29

Page1 Page2 Page3 Page4 Page5

セキュリティ・トークンと認証

 前述のUsernameToken要素で表されるセキュリティ・トークンによって表明された申告は、次の2点である。

  • 送信元はuser1である
  • 送信元はかくかくしかじかの秘密を受信先と共有している

 このように、メッセージの送信元の身元(アイデンティティ)に関する申告の表明が、本当に正しい申告であるかどうかを確認するプロセスのことを「認証」と呼ぶ。認証によって、送信元が誰なのか(または誰でないのか)が確認できる。

 WS-Security仕様には、申告の表明を具体的にどのように処理するかについては記述されていない。そのため、MicrosoftのWSEとIBMのWSTK(Web Services Toolkit)では異なる方法で認証処理を行っているのは前回解説したとおりだ。ここではMicrosoftのWSEの仕組みをもう一度おさらいしよう。

 前回紹介したWSEを用いたWebサービス・クライアントでは、次のようなコードでUsernameTokenをSOAPヘッダに添付していた。

localhost.Service1 svc = new localhost.Service1();

Microsoft.Web.Services.SoapContext ctx = svc.RequestSoapContext;
Microsoft.Web.Services.Security.UsernameToken user =
  new Microsoft.Web.Services.Security.UsernameToken("user1", "pass1",
    Microsoft.Web.Services.Security.PasswordOption.SendPlainText);
ctx.Security.Tokens.Add(user);
Webサービス呼び出し時に、SOAPヘッダにUsernameTokenを添付するためのコード

 Microsoft.Web.Services.Security.UsernameTokenクラスのコンストラクタの第3引数に「PasswordOption.SendPlainText」を指定している。このため、前回のサンプルでは次のようなUsernameTokenが送られていた。これは、WS-Security仕様で定義されている、パスワードをクリア・テキストで送信する手順で作成されたセキュリティ・トークンだ。

<wsse:UsernameToken
    xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
    wsu:Id="SecurityToken-85d37100-84fd-4378-99b1-8fe368508755">
  <wsse:Username>user1</wsse:Username>
  <wsse:Password Type="wsse:PasswordText">pass1</wsse:Password>
  <wsse:Nonce>kWzmUXFIHxnXQ+p7+NqsbA==</wsse:Nonce>
  <wsu:Created>2002-09-14T05:31:26Z</wsu:Created>
</wsse:UsernameToken>
UsernameTokenクラスで「SendPlainText」を指定した場合に作成される、パスワードがクリア・テキストなセキュリティ・トークンの例

 WSEでは、上記以外の2つの方法でもUsernameTokenを作成できる。まず、PasswordOption.SendNoneを指定すると、次のようなUsernameTokenが作成される。これは、上記で解説した、パスワードが指定されていないトークンだ。

<wsse:UsernameToken
    xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
    wsu:Id="SecurityToken-a36a8615-0f86-498e-be5e-c4b15dd65f01">
  <wsse:Username>user1</wsse:Username>
  <wsse:Nonce>NgJEugg7OzpgLSmRiA6Ymw==</wsse:Nonce>
  <wsu:Created>2002-10-21T02:38:17Z</wsu:Created>
</wsse:UsernameToken>
UsernameTokenクラスで「SendNone」を指定した場合に作成される、パスワードが指定されていないセキュリティ・トークンの例

 また、PasswordOption.SendHashedを指定すると、補遺で定義されたノンスとタイムスタンプを含んだパスワードのハッシュが作成される。

<wsse:UsernameToken
    xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
    wsu:Id="SecurityToken-139ac9b2-493d-4b3f-9fab-bb17038c86fe">
  <wsse:Username>
    user1
  </wsse:Username>
  <wsse:Password Type="wsse:PasswordDigest">
    tOVVSsx51jL/iXvzPnJ2gYSYvg4=
  </wsse:Password>
  <wsse:Nonce>
    v0yDmxGuLEdnqHY/2IXAow==
  </wsse:Nonce>
  <wsu:Created>
    2002-10-21T02:24:39Z
  </wsu:Created>
</wsse:UsernameToken>
UsernameTokenクラスで「SendHashed」を指定した場合に作成される、ノンスとタイムスタンプを含んだパスワードのハッシュを持つセキュリティ・トークンの例

 上述したとおり、SOAPメッセージの伝送路がエンド・ツー・エンドで信頼できる場合を除いて、パスワードは最低でもPasswordOption.SendHashedを指定して送信しなければならない。

 UsernameToken要素で送られたセキュリティ・トークンをサーバ側で処理するために、WSEはIPasswordProviderインターフェイスを利用する。XML Webサービスに送られてきたSOAPメッセージは、Web.configに追加されている次の要素によって、まずMicrosoft.Web.Services.WebServicesExtensionクラスによって処理される。この処理は、asmxファイル(とそのコードビハインド)による処理の前後に行われる。

<webServices>
  <soapExtensionTypes>
    <add type="Microsoft.Web.Services.WebServicesExtension, Microsoft.Web.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" priority="1" group="0"/>
  </soapExtensionTypes>
</webServices>
Webサービスに送られてきたSOAPメッセージを、Microsoft.Web.Services.WebServicesExtensionクラスで処理するように指示したWeb.configの要素

 WebServicesExtensionクラスは、SOAPヘッダのSecurity要素にUsernameToken要素を発見すると、IPasswordProviderインターフェイスを実装しているクラスのオブジェクトを作成して、そのGetPasswordメソッドを呼び出す。その際、引数としてUsernameToken要素のUsername要素の内容を渡す。IPasswordProviderインターフェイスを実装しているクラスは、Web.configの次の記述を参照して決められる。以下の場合では、「WSE1」という名前のアセンブリに含まれるWSE1.PasswordProviderクラスのオブジェクトが作成されるわけだ。

<microsoft.Web.Services>
  <security>
    <passwordProvider type="WSE1.PasswordProvider, WSE1" />
  </security>
</microsoft.Web.Services>
IPasswordProviderインターフェイスを実装したクラスを指定するためのWeb.configの記述例

 このクラスは、IPasswordProviderインターフェイスのGetPasswordメソッドを実装する。このメソッドの内容は、とにかくどんな方法でもいいので、引数として渡されたユーザー名に一致する正しいパスワードを取り出して、文字列で返すコードでなければならない。例えば、ユーザー名をキーにしてデータベースにアクセスし、パスワードを取得してもいいだろう。WSEの現在の実装では、サーバ側もパスワードのクリア・テキストを知っている必要がある。パスワードが前回のサンプルのように平文で送られていても、今回解説したようなダイジェストで送られていても、GetPasswordメソッドは平文のパスワードを返さなければならない(ただしクライアント側で先に暗号化したパスワードを送信できる場合は、サーバ側もその暗号化されたものだけを知っていればよい)。GetPasswordメソッドから返されたパスワードが、送られてきたパスワード(のエンコードを解除したもの)と一致すれば、WSEにおける認証はOKと見なされる。一致していなかった場合は、認証エラーを示すSOAP Faultが自動的に返され、asmxファイルのWebMethodは実行されない。なお、UsernameTokenにパスワードが指定されていない(PasswordOption.SendNone)場合は、GetPasswordメソッドは呼び出されるが、実はパスワードとして何を返しても、処理はそのまま素通りしてしまうことにも注意してほしい。

 ただし、SSLなどを使っていないために伝送路が信頼できない場合は、単純に平文でパスワードが一致しただけで認証をOKと見なしてはならない。メッセージを事前にのぞき見した悪意のクライアントが送信したものかもしれないからだ。従って上述したとおり、UsernameTokenにパスワードを含める場合は、クライアントは必ずWS-Securityの補遺に解説されているノンスとタイムスタンプとを組み合わせたダイジェストを送信してくる。そこでそれを受け取ったサーバ側では、単純な平文ではなくダイジェストが送られてきたことも併せて確認しなければならない*1

*1 さらに、リプレイ攻撃を防ぐために、ノンスとタイムスタンプに同じ値が繰り返し使われていないこともあわせて確認する必要がある。

 次のコードで、パスワードが送られてこなかった場合(PasswordOption.SendNone)とパスワードが平文で送られてきた場合(PasswordOption.SendPlainText)の両方に対処できる。このコードをGetPasswordメソッドの内部に書けば、単にパスワードが正しいかどうかだけではなく、その形式も含めてチェックすることができる。

if ((username.PasswordOption
    != Microsoft.Web.Services.Security.PasswordOption.SendHashed)) {
  throw new Microsoft.Web.Services.Security.SecurityFormatException(
    "Something bad happened because of you.");
}
WSEを用いたWebサービスで必要となる、パスワードがノンスとタイムスタンプとを組み合わせたダイジェストかどうかを確認するコード例

 受け取ったUsernameTokenのオプションをチェックすれば、どのようなトークンが送られたのかが分かる。


 INDEX
  特集 次世代XML Webサービスを試す Part 2
  WS-Security詳細解説
    1.WS-SecurityとWeb Services Enhancements
  2.セキュリティ・トークンと認証
    3.セキュリティ・トークンとしてのX.509v3証明書
    4.SOAPメッセージの完全性
    5.SOAPメッセージの秘匿性
 
 「特集:次世代XML Webサービスを試す」


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

本日 月間