次の方法で共有


ASP.NET を使用して作成した XML Web サービスのセキュリティ

XML Web サービスに最適なセキュリティ実装を決定するときは、まず 2 つの重要なセキュリティ原則である認証と認定について決定します。認証とは、ユーザーの名前やパスワードなどの資格情報に基づいた ID を証明機関に照会して検証するプロセスです。ID が認証されると、認定によって、その ID にリソースへのアクセス権を与えるかどうかが決定されます。

ASP.NET を使用して作成する XML Web サービスでは、ASP.NET によって提供される認証オプションおよび認定オプションや、カスタマイズされた SOAP ベースのセキュリティからセキュリティ オプションを選択できます。ASP.NET はインターネット インフォメーション サービス (IIS: Internet Information Services) と連動して、複数の認証オプションおよび認定オプションを提供します。また、SOAP ヘッダーを使用するなど、カスタム認証オプションを作成することもできます。さらに、ASP.NET には、クライアントの資格情報を使用して要求を実行する、偽装と呼ばれる機能も用意されています。偽装の使用方法については、「ASP.NET の偽装」を参照してください。

ここでは、ASP.NET を使用して作成する XML Web サービスで使用できる認証オプションおよび認定オプションの概要について説明します。ASP.NET Web アプリケーションで使用できるセキュリティ オプションの詳細については、「ASP.NET Web アプリケーションのセキュリティ」を参照してください。

XML Web サービスの認証オプション

ASP.NET を使用して作成した XML Web サービスには、クライアントを認証するためのオプションが複数あるため、特定の XML Web サービスに対して適切なオプションを選択することが重要です。適切なセキュリティ オプションを選択するときに、開発者が二者択一を迫られるものとして、セキュリティ レベルとパフォーマンスのどちらを選択するかという課題があります。一部の XML Web サービスでは、クライアントの資格情報をネットワーク経由で暗号化を使用して送信することが重要であるため、クライアントの資格情報を暗号化するアルゴリズムが必須となります。たとえば、クレジット カードを処理する XML Web サービスを記述する場合、開発者は、クレジット カード情報を暗号化するために追加のオーバーヘッドが生じることよりも、クライアントの資格情報が盗用される危険性の方を心配します。

ASP.NET を使用して作成した XML Web サービスで使用できる認証オプションを次の表にまとめます。先頭に Windows の付いたオプションは、ASP.NET を使用して作成する XML Web サービスに使用できる Microsoft Windows 認証オプションです。

認証オプションの概要

認証オプション 説明
Windows - 基本 クライアントの ID を保護しない場合に使用します。ユーザーの名前とパスワードは base64 エンコードされた文字列として書式なしテキストに保存されて送信されます。このタイプの認証では、パスワードとユーザー名はエンコードされますが、暗号化はされません。つまり、ネットワーク監視ツールを持つ悪意のあるユーザーにより、ユーザー名とパスワードが傍受される可能性があります。
Windows - 基本および SSL インターネットが介在する状況において、クライアントの ID を保護する場合に使用します。ユーザー名とパスワードは、書式なしテキストではなく、Secure Sockets Layer (SSL) 暗号化を使用してネットワーク経由で送信されます。この方法は、インターネットが介在する状況に対して簡単に構成し、機能させることができます。ただし、SSL を使用すると、パフォーマンスは低下します。
Windows - ダイジェスト インターネットが介在する状況において、クライアントの ID を保護する場合に使用します。ハッシュを使用して、クライアントの資格情報を暗号化して送信します。つまり、パスワードはクリア テキストでは送信されません。さらに、ダイジェスト認証はプロキシ サーバー経由で機能します。ただし、他のプラットフォームでもダイジェスト認証が広く採用されているわけではありません。
Windows - 統合 Windows NTLM または Kerberos を使用します。ユーザーの Web ブラウザ、Microsoft Internet Explorer との暗号交換を使用します。
Windows - クライアント証明書 インターネットおよびイントラネットが介在する状況において、クライアントの ID を保護する場合に使用します。各クライアントが、相互信頼を確立した証明機関から証明書を取得する必要があります。証明書は、オプションでユーザー アカウントに割り当てることもでき、XML Web サービスへのアクセス権を認証するために IIS によって使用されます。
フォーム XML Web サービスではサポートされていません。これは、HTTP クライアント側リダイレクトを使用して、認証されていない要求を HTML フォームにリダイレクトするシステムです。XML Web サービスの多くのクライアントは、UI を使用した資格情報の提供は行いません。したがって、ログオン フォームが使用されないように、フォーム認証以外の認証方法を使用する必要があります。
SOAP ヘッダー – カスタム インターネットが介在する状況において、ID を保護する場合と保護しない場合の両方に使用できます。ユーザーの資格情報は、SOAP メッセージの SOAP ヘッダー内に含めて渡されます。XML Web サービスを管理するプラットフォームに関係なく、Web サーバーがカスタム認証の実装を提供します。

上のすべてのオプション (SOAP ヘッダーの使用を除く) については、構成ファイルと IIS の組み合わせを使用して、セキュリティの設定が指定されます。構成ファイルの詳細については、「ASP.NET の構成」を参照してください。カスタム SOAP ヘッダー オプションについては、後の認定に関するセクションで、認証および認定を伴うソリューションとして詳しく説明します。

Windows 認証

IIS および ASP.NET は、Windows に組み込まれたセキュリティを使用した、XML Web サービスなどの Web アプリケーションの認証をサポートします。Windows には、認証オプションとして、基本、ダイジェスト、統合 Windows の 3 つのオプションがあります。さらに、各オプションと SSL を併用できます。基本以外のすべての Windows 認証オプションでは、データがなんらかの形式で暗号化されるため、SSL によって提供される追加の暗号化レベルが使用されるのは、通常は基本またはクライアント証明書と組み合わせて使用する場合に限られます。

使用する Windows 認証オプションの種類に関係なく、XML Web サービスと XML Web サービスのクライアント双方の設定は似ています。ただし、クライアント証明書は例外となるため、クライアント証明書を使用するサーバーとクライアントの設定手順は別に説明します。これらの認証オプションは構成ファイルと IIS で設定されているため、Windows 認証を使用するために XML Web サービスにコードを追加する必要はありません。ただし、クライアントの資格情報を XML Web サービスに渡すコードは、XML Web サービス クライアントに追加する必要があります。

XML Web サービスで使用する認証機構の一部として SSL を組み込む場合には、XML Web サービスを管理する Web アプリケーションまたは XML Web サービス自体に対して、IIS を使用して SSL を構成する必要があります。その結果、サービスの説明およびそのサービスの説明から生成されるプロキシ クラスにも、XML Web サービスが SSL を使用することが反映されます (SSL を使用してサービスの説明およびサービス ヘルプ ページにアクセスする場合)。サービスの説明内の XML Web サービスの URL の先頭には、https が付きます。SSL の設定の詳細については、IIS のドキュメントを参照してください。

Windows 認証を使用するように XML Web サービスを構成するには

  1. IIS を使用して、Windows 認証を使用するように XML Web サービスを構成します。

    IIS を使用すると、ディレクトリ レベルまたはファイル レベルでセキュリティを指定できます。XML Web サービスのセキュリティをファイルごとに指定する場合、IIS の .asmx ファイルで XML Web サービスに対するアクセス許可を設定します。.asmx ファイルは、XML Web サービスへのエントリ ポイントです。詳細については、IIS のドキュメントを参照してください。

  2. 構成ファイルを変更して Windows 認証を指定します。

    構成ファイルにある authentication XML 要素の mode 属性を "Windows" に設定します。構成ファイルの設定方法の詳細については、「ASP.NET の構成」を参照してください。構成ファイルを Windows 認証を使用するように変更するコード例を次に示します。

    // Fragment of a Web.config file.
    <authentication mode= "Windows">
    </authentication> 
    

Windows 認証を使用して XML Web サービスにクライアント証明書を渡すには

  1. XML Web サービスへのプロキシ クラスの新しいインスタンスを作成します。プロキシ クラスが生成されていない場合は、生成方法について、「XML Web サービス プロキシの作成」を参照してください。

  2. NetworkCredential クラスの新しいインスタンスを作成して、UserNamePassword、および Domain プロパティを設定します。

  3. CredentialCache の新しいインスタンスを作成します。

  4. CredentialCache の Add メソッドを使用して、NetworkCredentialCredentialCache に追加します。

  5. CredentialCache のインスタンスをプロキシ クラスの Credentials プロパティに割り当てます。

    統合 Windows 認証を使用する場合、Credentials プロパティを DefaultCredentials に設定する必要があります。

    Credentials プロパティを CredentialCache.DefaultCredentials に設定すると、サーバーの構成に応じて、クライアントはサーバーと Kerberos 認証や NTLM 認証を実行するためにネゴシエートします。

    Windows 認証を使用する XML Web サービス メソッドに渡されるクライアント証明書の設定例を次に示します。

    Imports System
    Imports System.Web.Services.Protocols
    Imports System.Net
    Imports MyMath
    
    Public Class Calculator
       Public Shared Sub Main()
         ' Create a new instance of the proxy class to an
         ' XML Web service method. 
         Dim mathproxy As MyMath.Math = New MyMath.Math()
    
         ' Create a new instance of CredentialCache.
         Dim mycredentialCache As CredentialCache = New CredentialCache()
    
         ' Create a new instance of NetworkCredential using the client
         ' credentials.
           Dim credentials As NetworkCredential = New _          NetworkCredential(UserName,SecurelyStoredPasword,Domain)
    
         ' Add the NetworkCredential to the CredentialCache.
           mycredentialCache.Add(New Uri(mathproxy.Url), "Basic", _                             credentials)
    
         ' Add the CredentialCache to the proxy class credentials.
         mathproxy.Credentials = mycredentialCache
    
         ' Call the method on the proxy class.
         Dim result As Integer 
         result = mathproxy.Add(3,5)
      End Sub
    End Class 
    [C#]
    using System;
    using System.Web.Services.Protocols;
    using System.Net;
    using MyMath;
    
    public class Calculator
    {
      public static void Main() 
      {
         // Create a new instance of the proxy class to an XML
         // Web service method. 
         MyMath.Math math = new MyMath.Math();
    
        // Create a new instance of CredentialCache.
        CredentialCache credentialCache = new CredentialCache();
    
       // Create a new instance of NetworkCredential using the client
       // credentials.
       NetworkCredential credentials = new
          NetworkCredential(UserName,SecurelyStroredPassword,Domain);
    
       // Add the NetworkCredential to the CredentialCache.
       credentialCache.Add(new Uri(math.Url),                        "Basic", credentials);
    
       // Add the CredentialCache to the proxy class credentials.
       math.Credentials = credentialCache;
    
         // Call the method on the proxy class.
         int result = math.Add(3,5);
      }
    }
    

クライアント証明書認証

クライアント証明書は、認証のための安全な機構を提供します。この機構では、クライアントはクライアント証明書と呼ばれる電子ドキュメントを送信するように要求され、Web サーバーとの SSL 接続を使用してクライアントが識別されます。SSL 接続により、クライアント証明書がネットワーク経由で送信されるときに、そのクライアント証明書に含まれるクライアント資格情報が暗号化されます。クライアントと Web サーバー間の通信は、クライアントによって送信される暗号化キーと Web サーバーによって提供されるキーの組み合わせを使用して暗号化されます。通信が確立されると、そのクライアント コンピュータとサーバー コンピュータだけが、その SSL 接続を使用して相互通信できます。

クライアント証明書は証明機関から取得できます。この証明機関は、Web サーバー自体またはクライアントとサーバーの両方が信頼している機関のいずれかにすることができます。証明書が取得され、クライアント証明書を受け入れるように Web サーバーが構成されていると、XML Web サービスが呼び出されたときに、クライアントはそのクライアント証明書を SSL 接続経由で Web サーバーに送信できます。クライアント証明書の詳細については、IIS のドキュメントを参照してください。

クライアント証明書認証を使用するように XML Web サービスを構成するには

クライアント証明書を使用してクライアントを認証するための、IIS の構成方法の概要を次に示します。詳細については、IIS のドキュメントを参照してください。

  1. SSL をインストールします。

  2. クライアント証明書を受け入れるように Web アプリケーション構成します。

  3. 構成ファイルを変更して、XML Web サービスに対して Windows 認証を指定します。

    構成ファイルにある authentication XML 要素の mode 属性を "Windows" に設定します。構成ファイルの設定方法の詳細については、「ASP.NET の構成」を参照してください。構成ファイルを Windows 認証を使用するように変更するコード例を次に示します。

    // Fragment of a Web.config file.
    <authentication mode= "Windows">
    </authentication>
    

Windows 認証を使用して XML Web サービスにクライアント証明書を渡すには

  1. XML Web サービスへのプロキシ クラスの新しいインスタンスを作成します。プロキシ クラスが生成されていない場合は、生成方法について、「XML Web サービス プロキシの作成」を参照してください。

  2. X509Certificate の新しいインスタンスを作成します。

  3. CreateFromCertFile メソッドを呼び出して、ファイルからクライアント証明書を読み込みます。

    クライアントは、信頼できる証明機関からクライアント証明書ファイルを取得できます。詳細については、IIS のドキュメントを参照してください。

  4. X509Certificate をプロキシ クラスの ClientCertificates コレクションに追加します。

    XML Web サービス クライアントがクライアント証明書を使用してその資格情報を渡す方法を次のコード例に示します。Web サーバーから発行されたクライアント証明書は、CreateFromCertFile メソッドを使用してファイルから読み込まれてから、プロキシ クラスの ClientCertificates プロパティに追加されます。

    ' Instantiate proxy class to a Bank XML Web service.
    Dim bank As BankSession = new BankSession()
    
    ' Load the client certificate from a file.
    Dim x509 As X509Certificate = X509Certificate.CreateFromCertFile("c:\user.cer")
    
    ' Add the client certificate to the ClientCertificates property
    ' of the proxy class.
    bank.ClientCertificates.Add(x509)
    
    ' Call the method on the proxy class, which requires authentication
    ' using client certificates.
    bank.Deposit(500)
    [C#]
    // Instantiate proxy class to a Bank XML Web service.
    BankSession bank = new BankSession();
    
    // Load the client certificate from a file.
    X509Certificate x509 = X509Certificate.CreateFromCertFile(@"c:\user.cer");
    
    // Add the client certificate to the ClientCertificates property
    // of the proxy class.
    bank.ClientCertificates.Add(x509);
    
    // Call the method on the proxy class, which requires
    // authentication using client certificates.
    bank.Deposit(500);
    

XML Web サービスの認定オプション

認定の目的は、ある ID に対して特定のリソースへの要求された種類のアクセス権を与えるかどうかを判断することです。特定のリソースへのアクセス権を認定する基本的な方法には、ファイル認定と URL 認定の 2 種類があります。IIS ではファイルごとにアクセス許可が設定されているため、ファイル認定は Windows 認証が使用されていれば使用できます。URL 認定は、ASP.NET によってサポートされている組み込みの認定機構のいずれかと一緒に使用できます。URL 認定の構成は、構成ファイルで行うことができます。この構成ファイルを使用して、.asmx ファイルなどの ASP.NET に関連付けられているファイルへのアクセス権をユーザーに対して個別に与えたり、拒否したりできます。

ファイルごとの認定の設定については、IIS のドキュメントを参照してください。

構成ファイルを使用した認定の設定については、「ASP.NET の認定」を参照してください。

SOAP ヘッダー – カスタム ソリューション

クライアント証明書などの Windows 認証機構は HTTP トランスポートに依存しますが、SOAP はトランスポートに依存しません。ASP.NET を使用して作成した XML Web サービスでは、HTTP 上で SOAP を使用します。そのため、カスタム認証機構を作成する 1 つの理由としては、認証をトランスポートから分離させることが挙げられます。これは、認証資格情報を SOAP ヘッダーに含めて渡すことによって実現できます。

SOAP ヘッダーは、XML Web サービスのセマンティクスに関連のない帯域外情報を渡すときにたいへん役立ちます。SOAP メッセージの Body 要素は、XML Web サービス メソッドの In パラメータと Out パラメータを含むため、その XML Web サービスによって処理されますが、それとは異なり、Header 要素は省略でき、したがってインフラストラクチャによって処理されます。つまり、カスタム認証機構を提供するために開発されたインフラストラクチャによって処理されます。

次のカスタム ソリューションは ASP.NET を使用して作成されており、SOAP ヘッダーを使用して認証機構を提供します。ソリューションの作成手順は、次のとおりです。

  • XML Web サービスを管理する Web サーバー上で実行するカスタム Http Module を作成します。
  • この Http Module が HTTP メッセージを解析し、そのメッセージが SOAP メッセージかどうかを確認します。
  • Http Module は、メッセージが SOAP メッセージであると判断した場合は、その SOAP ヘッダーを読み取ります。
  • SOAP メッセージの SOAP ヘッダーに認証資格情報が含まれている場合、Http Module はカスタム global.asax イベントを発生させます。

XML Web サービスを変更してカスタムの SOAP ヘッダー認証を使用するには、その XML Web サービスで、認証資格情報を含む SOAP ヘッダーを必要とすることを指定し、その XML Web サービスへのクライアントからのアクセス権を認定する必要があります。提示している例では、Http Module がユーザーを認証し、Context プロパティを設定しています。XML Web サービスは、これらのプロパティを使用して、クライアントに XML Web サービスへのアクセス権が認定されているかどうかを判断できます。

XML Web サービス クライアントは、要求される SOAP ヘッダーを SOAP 要求に追加して、クライアント資格情報をヘッダーに読み込むことによって、クライアント資格情報を XML Web サービスに送信します。この例では、テキストがネットワーク経由で明確に読み取ることができるテキスト (つまり、暗号化されない) で送信されています。クリア テキストではアプリケーションの保護が不十分な場合は、暗号化アルゴリズムを追加してください。

SOAP 要求に対して HTTP メッセージを解析する Http Module のコード例を次に示します。HTTP メッセージが SOAP メッセージである場合、カスタム WebServiceAuthenticationEvent が発生します。

using System;
using System.Web;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Text;
using System.Web.Services.Protocols;

namespace Microsoft.WebServices.Security {

      public sealed class WebServiceAuthenticationModule : IHttpModule 
      {
         private WebServiceAuthenticationEventHandler 
                       _eventHandler = null;

         public event WebServiceAuthenticationEventHandler Authenticate 
         {
           add { _eventHandler += value;}
           remove {_eventHandler -= value;}
         }
 
         public void Dispose() 
         {
         }

         public void Init(HttpApplication app) 
         {
           app.AuthenticateRequest += new
                      EventHandler(this.OnEnter);
         }

         private void OnAuthenticate(WebServiceAuthenticationEvent e) 
         {
           if (_eventHandler == null)
               return;

             _eventHandler(this, e);
             if (e.User != null)
                e.Context.User = e.Principal;
         }

         public string ModuleName
         {
           get{ return "WebServiceAuthentication"; }
         }

         void OnEnter(Object source, EventArgs eventArgs) {
           HttpApplication app = (HttpApplication)source;
           HttpContext context = app.Context;
           Stream HttpStream = context.Request.InputStream;

           // Save the current position of stream.
           long posStream = HttpStream.Position;

           // If the request contains an HTTP_SOAPACTION 
           // header, look at this message.
           if (context.Request.ServerVariables["HTTP_SOAPACTION"]                          == null)
              return;

           // Load the body of the HTTP message
           // into an XML document.
           XmlDocument dom = new XmlDocument();
           string soapUser;
           string soapPassword;

           try 
           {
             dom.Load(HttpStream);

             // Reset the stream position.
             HttpStream.Position = posStream;

             // Bind to the Authentication header.
             soapUser =
                 dom.GetElementsByTagName("User").Item(0).InnerText;
             soapPassword =
                 dom.GetElementsByTagName("Password").Item(0).InnerText;
           } 
           catch (Exception e) 
           {
             // Reset the position of stream.
             HttpStream.Position = posStream;

             // Throw a SOAP exception.
             XmlQualifiedName name = new
                          XmlQualifiedName("Load");
             SoapException soapException = new SoapException(
                       "Unable to read SOAP request", name, e);
             throw soapException;
           }

           // Raise the custom global.asax event.
           OnAuthenticate(new WebServiceAuthenticationEvent                        (context, soapUser, soapPassword));
           return;
      }
    }
}

SOAP 要求を受信したときに、Http Module が発生させるカスタム認証イベントのコード例を次に示します。

namespace Microsoft.WebServices.Security {
    using System;
    using System.Web;
    using System.Security.Principal;

    public class WebServiceAuthenticationEvent : EventArgs {
       private Iprincipal _IPrincipalUser;
       private HttpContext _Context;
       private string _User;
       private string _Password;

       public WebServiceAuthenticationEvent(HttpContext context)
       {
            _Context = context;
       }

       public WebServiceAuthenticationEvent(HttpContext context,
                       string user, string password)
       {
           _Context = context;
           _User = user;
           _Password = password;
       }
       public  HttpContext Context 
       { 
         get { return _Context;}
       }
       public IPrincipal Principal 
       { 
         get { return _IPrincipalUser;} 
         set { _IPrincipalUser = value;}
       }
       public void Authenticate()
       {
         GenericIdentity i = new GenericIdentity(User);
         this.Principal = new GenericPrincipal(i, new String[0]);
       }
       public void Authenticate(string[] roles)
       {
         GenericIdentity i = new GenericIdentity(User);
         this.Principal = new GenericPrincipal(i, roles);
       }
       public string User 
       {
         get { return _User; }
         set { _User = value; }
       }
       public string Password
       {
         get { return _Password; }
         set { _Password = value; }
       }
       public bool HasCredentials {
         get 
         {
              if ((_User == null) || (_Password == null))
                return false;
              return true;
         }
       }
    }
}

カスタム WebServiceAuthenticationEvent イベントのデリゲートのコード例を次に示します。

namespace Microsoft.WebServices.Security 
{
   using System;

   public delegate void WebServiceAuthenticationEventHandler(Object sender,  WebServiceAuthenticationEvent e);
}

クライアントが渡す必要のある Authentication SOAP ヘッダーを定義する XML Web サービスのコード例を次に示します。XML Web サービスでは、認証を行う必要はありません。代わりに、User.Identity.IsAuthenticated プロパティを調べて、Http Module がユーザーを認証しているかどうかを確認します。

<%@ WebService Language="C#" Class="SecureWebService" %>

using System;
using System.Web.Services;
using System.Web.Services.Protocols;

public class Authentication : SoapHeader {
  public string User;
  public string Password;
}

public class SecureWebService : WebService{
  public Authentication authentication;

  [WebMethod]
  [SoapHeader("authentication")]
  public string ValidUser(){
    if (User.IsInRole("Customer"))
      return "User is in role customer";

    if (User.Identity.IsAuthenticated)
      return "User is a valid user";
    return "not authenticated";
  }
}

Authentication SOAP ヘッダー内のカスタム SOAP ヘッダー認証機構に必要な資格情報を渡す XML Web サービス クライアントのコード例を次に示します。

    // Create a new instance of an XML Web service proxy class.
    SecureWebService s = new SecureWebService();

    // Create the Authentication SOAP header and set values.
    Authentication a = new Authentication();
    a.User = user.Value;
    a.Password = password.Value;

    // Assign the Header.
    s.AuthenticationValue = a;

      string result = s.ValidUser();
      span1.InnerHtml = result;

参照

ASP.NET Web アプリケーションのセキュリティ | ASP.NET の構成 | ASP.NET を使用した XML Web サービスの作成 | NetworkCredential クラス | CredentialCache クラス | X509Certificate クラス