Search code examples
asp.netwcfdnswcf-securitywcf-client

Is there a way to pass domain credentials from the originating browser in webHttpBinding wcf service?


Is there a way to pass domain credentials from the originating browser in webHttpBinding WCF service? I'm thinking this should be possible as when I log into any aspx page with Windows Authentication enabled in IIS, I can get the calling user's domain credentials. How would I setup my WCF service in such a manner? Currently the user identity I get in the WCF service are those of the app pool the svc is running under?

EDIT

I don't have .NET 4 -- My configuration file is below, but I still get an error:

Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.

Should I explicitly enable Anonymous for that path in IIS? I think this would undo my efforts to get the domain name.

<behaviors>
<endpointBehaviors>
    <behavior name="Awesome.Project.OperationsBehavior">
        <enableWebScript />
    </behavior>
</endpointBehaviors>
</serviceBehaviors>
    <behavior name="Awesome.Project.OperationsServiceBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
</serviceBehaviors>
</behaviors>

<services>
      <service behaviorConfiguration="Awesome.Project.OperationsServiceBehavior"
        name="Awesome.Project.Operations">
        <endpoint address="" binding="webHttpBinding" 
         contract="Awesome.Project.Operations" 
         behaviorConfiguration="Awesome.Project.OperationsBehavior" 
         bindingName="windowsSecurityWebHttpBinding">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <!--<endpoint address="mex" binding="mexHttpBinding" 
             contract="IMetadataExchange" />-->
      </service>
</services>

<bindings>
    <webHttpBinding>
        <binding name="windowsSecurityWebHttpBinding">
            <security mode="Transport">
                <transport clientCredentialType="Windows"/>
            </security>
        </binding>
    </webHttpBinding>
</bindings>

Solution

  • You need to turn on authentication in the service - assuming .NET 4 add the following to your config

    <bindings>
      <webHttpBinding>
        <binding>
          <security mode="Transport">
            <transport clientCredentialType="Windows"/>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    

    for .NET 3.5 or 3.0 you need

    <bindings>
      <webHttpBinding>
        <binding name="webBindingConfig">
          <security mode="Transport">
            <transport clientCredentialType="Windows"/>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    
    <services>
      <service ...>
        <endpoint bindingConfiguration = "webBindingConfig" binding="webHttpBinding" .../>
      </service>
    </services>
    

    Edit for additional questions:

    WCF will generally not pass credentials over non secured transports - that's why mode="Transport" is important. If you got rid of it its the same as Mode="None" for WebHttpBinding

    If the site is considered to be in the intranet zone then IE will pass the user's credentials automatically. However, non-IE browsers will not and so will hit the site anonymously before getting a 401 and then sending the credentials. The intial request requires anonymous access to be supported in IIS as WCF handles the authentication mechanism

    If you need to get hold of HttpContext you can use Asp.NET Compatibility. However in WCF you can use ServiceSecurityContext.Current.PrimaryIdentity.Name to get the authenticated user