在ASP.NET兼容模式下运行的WCF服务中,HttpContext为null

时间:2010-11-01 15:59:23

标签: wcf wcf-security

我有一个托管WCF服务的asp.net网站。然后从桌面应用程序访问此服务。在我的服务中,在我的UserNamePasswordValidator类的实现中执行Validate方法期间,HttpContext始终为null。我使用Username作为客户端凭据类型。我需要访问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 is not initialised on first call bug,但是对于我对服务的每次通话都会发生这种情况,即使我多次在同一个连接上调用相同的方法

编辑:澄清问题以回答marc_s的评论和Aliostad的问题

编辑:添加以下链接,表明http上下文不应为空

有人可以帮我借这个吗?我宁愿不必将网站的Url放在我所有网站的appSettings配置部分。

4 个答案:

答案 0 :(得分:2)

问题是你想从Validate方法访问HttpContext。据我所知,内部WCF实现Validate方法在不同的线程中运行。通过设计,该线程无法访问处理请求的主线程可用的任何上下文。在Validate方法中,您无法访问任何基于WCF的上下文(OperationContext,ServiceSecurityContext等),因此我认为它与HttpContext相同。

答案 1 :(得分:1)

UserNamePasswordValidator的validate方法在asp.net管道初始化之前执行。所以HttpContext为null。请尝试使用OperationContext。

答案 2 :(得分:0)

我不清楚你要做什么。

只有当我使用不需要绑定配置的新WCF REST API时,

aspNetCompatibilityEnabled才有意义 - 据我所知。 WCF REST中的绑定由ASP.NET MVC路由管理。

如果您使用配置API设置经典绑定,那么您没有使用新功能,因此“no aspNetCompatibilityEnabled for you”!

答案 3 :(得分:0)

所以最后我想到了一个解决方法。我通过username参数将服务运行的url传递给UserNamePasswordValidator.Validate。我使用格式$ username $ | $ siteurl $。然后在服务器上我将两者分开。需要注意的一点是,

ServiceSecurityContext.Current.PrimaryIdentity.Name
属性将为请求的其余部分包含$ username $ | $ siteurl $,因此每次要访问它时都必须将其拆分为其组件。

只是为了澄清为什么我需要这样做。我们的系统可以在同一主目录中运行具有不同URL的多个站点,每个站点都具有与URL关联的单独身份验证。所以没有网址我无法验证请求。我一直在使用appSetting键来提供网址,但这意味着每个网站都必须有自己的主目录。

相关问题