Получить IP-адрес клиента для WCF, после операции - PullRequest
11 голосов
/ 27 августа 2010

Я пытаюсь определить 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-адрес и порт, по которому клиентское соединение вошло в сервис.Получение этой информации довольно просто.Просто извлеките его из IncomingMessageProperties текущего OperationContext с помощью RemoteEndpointMessageProperty.Name и получите доступ к свойствам адреса и порта.

> [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.Код работает, когда клиентский запрос является WebGet.Но когда клиентский запрос является WebInvoke, я получу IP-адрес хоста WCF.Любое решение?Спасибо.

Вот интерфейс

[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();
    ...
} 

1 Ответ

0 голосов
/ 17 августа 2014

Вы пытались использовать 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);
            }
...