HttpContext является нулевым в службе WCF, работающей в режиме совместимости ASP.NET - PullRequest
3 голосов
/ 01 ноября 2010

У меня есть сайт asp.net, на котором размещается служба WCF.Затем эта служба доступна из настольного приложения.В моем сервисе HttpContext всегда имеет значение null во время выполнения метода Validate в моей реализации класса UserNamePasswordValidator.Я использую имя пользователя в качестве типа учетных данных клиента.Мне нужен доступ к контексту http, чтобы получить URL-адрес, с которого был получен доступ к сервису, чтобы правильно проверить имя пользователя и пароль, так как к сайту можно обращаться по разным URL-адресам, и у каждого из них свое хранилище.

Следующий атрибут в классе, который содержит метод, который будет вызываться после класса валидатора (и также класса валидатора)

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

У меня служба настроена следующим образом:

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="wsHttpSecurityOptions">
        <security mode="Message">
          <message clientCredentialType="UserName" establishSecurityContext="true" negotiateServiceCredential="true"/>
          <transport clientCredentialType="Certificate" proxyCredentialType="None"/>
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
    <behavior name="SecurityServiceBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFServer.MyAuthenticator" includeWindowsGroups="false"/>
        <serviceCertificate findValue="myurl.com" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
      </serviceCredentials>
    </behavior>
    </serviceBehaviors>
  </behaviors>
  <services>
    <service behaviorConfiguration="SecurityServiceBehavior" name="Test.WCF.Actions">
      <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpSecurityOptions" contract="WCFServer.IActions"/>
    </service>
  </services>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>

Я видел, что HttpContext не инициализируется при ошибке первого вызова , но это происходит со мной при каждом обращении к службе, даже когда я вызываю один и тот же метод в том же соединении болееоднажды

Редактировать: уточненный вопрос для ответа на комментарий marc_s и вопрос Алиостада

Редактировать: Добавлены следующие ссылки, которые указывают, что http-контекст не должен быть нулевым

Кто-нибудь может мне помочь, пожалуйста?Я бы предпочел не указывать URL-адрес сайта в разделе конфигурации appSettings для всех моих сайтов.

Ответы [ 4 ]

2 голосов
/ 07 ноября 2010

Проблема в том, что вы хотите получить доступ к HttpContext из метода Validate.Как я понимаю, внутренняя реализация WCF метод Validate работает в другом потоке.По своей структуре этот поток не имеет доступа ни к какому контексту, доступному основному потоку, обрабатывающему запрос.В методе Validate вы не можете получить доступ к любому контексту на основе WCF (OperationContext, ServiceSecurityContext и т. Д.), Поэтому я думаю, что это будет то же самое с HttpContext.

1 голос
/ 12 ноября 2010

Метод validate UserNamePasswordValidator выполняется до инициализации конвейера asp.net. Таким образом, HttpContext является нулевым. Попробуйте вместо этого использовать OperationContext.

0 голосов
/ 28 июня 2011

Итак, наконец, я подумал об обходном пути. Я передаю URL-адрес, в котором работает служба, в UserNamePasswordValidator.Validate через параметр username. Я использую формат $ username $ | $ siteurl $. Затем на сервере я разделяю их. Следует отметить, что свойство

ServiceSecurityContext.Current.PrimaryIdentity.Name
будет содержать $ username $ | $ siteurl $ для остальной части запроса, поэтому вам придется разбивать его на компонент каждый раз, когда вы захотите получить к нему доступ.

Просто чтобы уточнить, зачем мне это нужно. Наша система может запускать несколько сайтов с разными URL-адресами в одном домашнем каталоге, каждый с отдельной аутентификацией, привязанной к URL-адресу. Поэтому без URL я не могу подтвердить подлинность запроса. Я использовал ключ appSetting для предоставления URL, но это означало, что каждый сайт должен иметь свой собственный домашний каталог.

0 голосов
/ 01 ноября 2010

Мне не ясно, что вы пытаетесь сделать.

aspNetCompatibilityEnabled имеет смысл, насколько я знаю, только тогда, когда вы используете новый API REST WCF, для которого не требуется конфигурация привязки.Привязка в WCF REST управляется маршрутизацией ASP.NET MVC.

Если вы используете API настройки для настройки классической привязки, то вы не используете новую функцию, поэтому " no aspNetCompatibilityEnabled for you"!

...