12

このリンクに従ってクライアントの IP アドレスを特定しようとしています: http://www.danrigsby.com/blog/index.php/2008/05/21/get-the-clients-address-in-wcf/

.Net 3.0 では、WCF サービスに接続しているクライアントのアドレスを取得する信頼できる方法がありませんでした。.Net 3.5 では、RemoteEndpointMessageProperty という新しいプロパティが導入されました。このプロパティは、クライアント接続がサービスに入った IP アドレスとポートを提供します。この情報を取得するのは非常に簡単です。RemoteEndpointMessageProperty.Name によって現在の OperationContext の IncomingMessageProperties からプルし、Address プロパティと Port プロパティにアクセスするだけです。

> [ServiceContract] public interface IMyService {
>     [OperationContract]
>     string GetAddressAsString(); }
> 
> public class MyService : IMyService {
>     public string GetAddressAsString()
>     {
>         RemoteEndpointMessageProperty clientEndpoint =
>             OperationContext.Current.IncomingMessageProperties[
>             RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
> 
>         return String.Format(
>             "{0}:{1}",
>             clientEndpoint.Address, clientEndpoint.Port);
>     } } 

注意事項:

  1. このプロパティは、http および tcp トランスポートでのみ機能します。MSMQ や NamedPipes などの他のすべてのトランスポートでは、このプロパティは使用できません。
  2. アドレスとポートは、サービスのマシンのソケットまたは http.sys によって報告されます。そのため、クライアントがアドレスを変更した VPN またはその他のプロキシを介してアクセスした場合、クライアントのローカル アドレスの代わりにその新しいアドレスが表示されます。これは、サービスがクライアントを認識しているアドレスとポートであり、クライアントが認識しているアドレスとポートではないため、望ましく重要です。これは、スプーフィングが行われている可能性があることも意味します。クライアントまたはクライアントとサーバーの間の何かが、アドレスを偽装する可能性があります。そのため、他のカスタム チェック メカニズムを追加しない限り、セキュリティの決定にアドレスまたはポートを使用しないでください。
  3. サービスで二重化を使用している場合は、サービスがクライアントに対してこのプロパティを設定するだけでなく、クライアントもそのサービスからの呼び出しごとにサービスに対してこのプロパティを設定します。

WebInvoke/Post と WebGet の operationContracts があります。このコードは、クライアント リクエストが WebGet の場合に機能します。しかし、クライアント リクエストが WebInvoke の場合は、WCF ホスト IP を取得します。解決策はありますか?ありがとう。

ここにインターフェースがあります

[OperationContract]
[WebGet(UriTemplate = RestTemplate.hello_get)]
Stream hello_get();

[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = RestTemplate.hello_post)]
Stream hello_post();

// Code for getting IP
private string getClientIP()
{
    //WebOperationContext webContext = WebOperationContext.Current;

    OperationContext context = OperationContext.Current;

    MessageProperties messageProperties = context.IncomingMessageProperties;

    RemoteEndpointMessageProperty endpointProperty =

    messageProperties[RemoteEndpointMessageProperty.Name]

    as RemoteEndpointMessageProperty;
    return endpointProperty.Address;
}

public Stream hello_get()
{
    string ip = getClientIP();
    ...
}

public Stream hello_post()
{
    string ip = getClientIP();
    ...
} 
4

1 に答える 1

-1

HttpContext を使用してみましたか? すべての WCF モードで使用できるわけではありませんが、環境によっては機能する可能性があります。

if (HttpContext.Current != null)
            {
                Trace.WriteLine(
                    "Who's calling? IP address: '{0}', Name: '{1}', User Agent: '{2}', URL: '{3}'.",
                    HttpContext.Current.Request.UserHostAddress, HttpContext.Current.Request.UserHostName,
                    HttpContext.Current.Request.UserAgent, HttpContext.Current.Request.Url);
            }
于 2014-08-17T19:07:55.237 に答える