wcfwcf-security

HttpContext is null in WCF service running in ASP.NET Compatibility Mode


I have a asp.net website that is hosting a WCF service. This service is then accessed from a desktop app. In my service the HttpContext is always null during the execution of the Validate method in my implementation of the UserNamePasswordValidator class. I'm using Username as the client credential type. I need access to the http context in order to get the Url the service was accessed from in order to validate the username and password correctly as the site can be accessed using different Urls and each one has a different user store.

The following attribute on the class that contains the method that will be called after the validator class (and the validator class as well)

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

I have a service is configured as follows:

<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>

I've seen the HttpContext is not initialised on first call bug but this happens to me for every call I make to the service, even when I call the same method on the same connection more than once

Edit: clarified question to answer marc_s's comment and Aliostad's question

Edit: Added following links that suggest the http context should not be null

Can anyone lend me a hand with this please? I'd rather not have to put the site's Url in the appSettings config section for all my sites.


Solution

  • So finally I thought of a workaround. I pass the url that the service is running in to the UserNamePasswordValidator.Validate though the username parameter. I use the format $username$|$siteurl$. Then at the server I separate the two. One thing to note is the

    ServiceSecurityContext.Current.PrimaryIdentity.Name
    property will then contain $username$|$siteurl$ for the rest of the request so you have to split it into its component everytime you want to access it.

    Just to clarify why I need to do this. Our system can run multiple sites with different urls on the same home directory, each with separate authentication that is tied to the url. So without the url I can't authenticate the request. I had been using an appSetting key to provide the url but that meant each site had to have its own home directory.