Подтвердить что ты не робот

Получить IP-адрес клиента для WCF, после операции

Я пытаюсь определить 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);
>     } } 

Примечания:

  • Это свойство работает только на транспорте http и tcp. По всем другим таких как MSMQ и NamedPipes, это свойство не будет доступный.
  • Адрес и порт сообщаются сокетом или http.sys услуг. Так что если клиент пришел через VPN или какой-то другой прокси, который изменил адрес, этот новый адрес будет вместо локального адреса клиентов. Это желательно и важно, потому что это адрес и порт, которые служба видит клиента как, а не как клиент видит себя как. Это также означает что может произойти некоторая подделка. Клиент или что-то в между клиентом и сервером может обмануть адрес. Поэтому не используйте адрес или порт для любых решений безопасности, если вы не добавили некоторые другие пользовательские механизмы проверки.
  • Если вы используете дуплекс службы, то не только сервис будет иметь это свойство для клиента, но клиент также будет иметь это свойство, заселенное для обслуживания для каждого вызова из этой службы.

У меня есть OperationContracts 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();
    ...
} 
4b9b3361

Ответ 1

Вы пытались использовать HttpContext? Он недоступен во всех режимах WCF, но это может работать в зависимости от вашей среды:

if (HttpContext.Current != null)
            {
                Trace.WriteLine(
                    "Who 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);
            }