リモート処理の例 : インターネット インフォメーション サービス (IIS: Internet Information Services) でのホスティング

基本の Web サービスを実装するサンプルを次に示します。このサンプルには、複雑な部分が数箇所含まれています。ペイロードを小さくし、システムによるストリームのシリアル化や逆シリアル化にかかる時間を短縮するため、BinaryFormatter が使用されます。さらに、IIS が Windows 統合認証 (NTLM 認証とも呼ばれます) を使用する場合、サーバーがクライアントを認証し、IIS が認証できた ID をクライアントに返します。最後に、クライアント構成ファイル内の URL を変更してプロトコル スキームに "https" を使用し、さらに IIS を構成して該当の仮想ディレクトリに SSL (Secure Sockets Layer) 暗号化を要求することによって、Web サービスを保護できます。

Caution note注意 :

.NET Framework リモート処理は、既定では認証または暗号化を実行しません。したがって、クライアントやサーバーとリモートで通信する前に、それらの ID の確認に必要な手順をすべて実行することをお勧めします。.NET Framework リモート処理アプリケーションの実行には、FullTrust アクセス許可が必要です。認証されていないクライアントがサーバーへのアクセスを許可された場合は、完全な信頼を与えられていると見なされ、コードの実行が可能になってしまいます。IIS でリモート型をホストするか、リモート型をホストするためのカスタム チャネル シンク ペアを構築することによって、常にエンドポイントを認証し、通信ストリームを暗号化してください。

このサンプルをコンパイルして実行するには

  1. RemoteIIS という名前のディレクトリ内にあるすべてのファイルを保存します。

  2. コマンド プロンプトで、次のコマンドを入力してサンプル全体をコンパイルします。

    [Visual Basic]

    vbc /t:library ServiceClass.vb
    vbc /r:System.Runtime.Remoting.dll /r:ServiceClass.dll Client.vb
    

    [C#]

    csc /t:library ServiceClass.cs
    csc /r:System.Runtime.Remoting.dll /r:ServiceClass.dll Client.cs
    
  3. \bin サブディレクトリを作成し、このディレクトリに ServiceClass.dll をコピーします。

  4. IIS でアプリケーションを作成します。アプリケーションのエイリアスを "HttpBinary" とし、ソース ディレクトリを "RemoteIIS" ディレクトリに設定します。

  5. この仮想ディレクトリの認証方法を統合 Windows 認証 (以前の NTLM 認証) に設定します。匿名アクセスを選択すると、HttpContext.Current.User.Identity.Namenull になり、GetServerString はユーザー エイリアスに "***unavailable***" を返します。これを防ぐためには、匿名アクセスの選択を解除します。

  6. IIS が開始されていることを確認します。コマンド プロンプトで "RemoteIIS" ディレクトリから「client」と入力します。

このアプリケーションは、1 台のコンピュータ上で、またはネットワーク経由で実行されます。このアプリケーションをネットワーク上で実行する場合、クライアント構成の "localhost" をリモート コンピュータの名前に置き換える必要があります。

ServiceClass

[Visual Basic]

Imports System
Imports System.Runtime.Remoting
Imports System.Web

Public Interface IService
    Function GetServerTime() As DateTime
    Function GetServerString() As String
End Interface

Public Class ServiceClass
    Inherits MarshalByRefObject
    Implements IService

    Private InstanceHash As Integer

    Public Sub New()
        InstanceHash = Me.GetHashCode()
    End Sub

    Public Function GetServerTime() As Date Implements IService.GetServerTime
        Return DateTime.Now
    End Function

    Public Function GetServerString() As String Implements IService.GetServerString
        ' Use the HttpContext to acquire what IIS thinks the client's identity is.
        Dim temp As String = HttpContext.Current.User.Identity.Name

        If (temp Is Nothing Or temp.Equals(String.Empty)) Then
            temp = "**unavailable**"
        End If

        Return "Hi there. You are being served by instance number: " _
            & InstanceHash.ToString() _
            & ". Your alias is: " _
            & temp
    End Function
End Class

[C#]

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Threading;
using System.Web;

public interface IService
{
   DateTime GetServerTime();
   string GetServerString();
}

// IService exists to demonstrate the possibility of publishing only the interface.
public class ServiceClass : MarshalByRefObject, IService
{
   private int InstanceHash;

   public ServiceClass()
   {
      InstanceHash = this.GetHashCode();
   }

   public DateTime GetServerTime()
   {
      return DateTime.Now;
   }

   public string GetServerString()
   {
      // Use the HttpContext to acquire what IIS thinks the client's identity is.
      string temp = HttpContext.Current.User.Identity.Name;
      if (temp == null || temp.Equals(string.Empty))
         temp = "**unavailable**";
      return "Hi there. You are being served by instance number: " 
         + InstanceHash.ToString() 
         + ". Your alias is: " 
         + temp;
   }
}

Web.config

<configuration>
   <system.runtime.remoting>
      <application>
         <service>
            <wellknown 
               mode="SingleCall" objectUri="SAService.rem"
               type="ServiceClass, ServiceClass"/>
         </service>
         <channels>
            <channel ref="http"/>
         </channels>
      </application>
   </system.runtime.remoting>
</configuration>

Client

[Visual Basic]

Imports System
Imports System.Collections
Imports System.Net
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Security.Principal

Public Class Client

    Public Shared Sub Main()
        ' Tells the system about the remote object and customizes the HttpChannel
        ' to use the binary formatter (which understands that base64 encoding is needed).
        RemotingConfiguration.Configure("Client.exe.config", False)

        ' New proxy for the ServiceClass.
        ' If you publish only the IService interface, you must use Activator.GetObject.
        Dim service As ServiceClass = New ServiceClass()

        ' Programmatically customizes the properties given to the channel. This sample uses the
        '  application configuration file.
        Dim Props As IDictionary = ChannelServices.GetChannelSinkProperties(service)
        Props.Item("credentials") = CredentialCache.DefaultCredentials

        ' Reports the client identity name.
        Console.WriteLine("ConsoleIdentity: " & WindowsIdentity.GetCurrent().Name)

        ' Writes what the server returned.
        Console.WriteLine("The server says : " & service.GetServerString())
        Console.WriteLine("Server time is: " & service.GetServerTime())
    End Sub
End Class

[C#]

using System;
using System.Collections;
using System.Net;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Security.Principal;

class Client
{
    static void Main(string[] args)
    {
        // Tells the system about the remote object and customizes the HttpChannel
        // to use the binary formatter (which understands that base64 encoding is needed).
        RemotingConfiguration.Configure("Client.exe.config", false);

        // New proxy for the ServiceClass.
        // If you publish only the IService interface, you must use Activator.GetObject.
        ServiceClass service = new ServiceClass();

        // Programmatically customizes the properties given to the channel. This sample uses the
        // application configuration file.
        IDictionary Props = ChannelServices.GetChannelSinkProperties(service);
        Props["credentials"] = CredentialCache.DefaultCredentials;

        // Reports the client identity name.
        Console.WriteLine("ConsoleIdentity: " + WindowsIdentity.GetCurrent().Name);

        // Writes what the server returned.
        Console.WriteLine("The server says : " + service.GetServerString());
        Console.WriteLine("Server time is: " + service.GetServerTime());
    }
}

Client.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <channels>
        <channel ref="http" useDefaultCredentials="true" port="0">
          <clientProviders>
            <formatter 
               ref="binary"
                  />
          </clientProviders>
        </channel>
      </channels>
      <client>
        <wellknown 
           url="https://localhost:80/HttpBinary/SAService.rem"
           type="ServiceClass, ServiceClass"
            />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>

関連項目

概念

リモート アプリケーションの構成
インターネット インフォメーション サービス (IIS) でのリモート オブジェクトのホスト

その他の技術情報

リモート処理の例

Footer image

Copyright © 2007 by Microsoft Corporation.All rights reserved.