0
votes

I have a WCF service decorated with:

[OperationBehavior(Impersonation = ImpersonationOption.Allowed)]

I'd like to configure in Web.Config credentials of the user that will be used to impersonate during service invocation. The user is windows domain user (credentials are: domain\username and password) Here is my config:

<behaviors>
  <serviceBehaviors>
    <behavior name="MetadataBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <serviceAuthorization impersonateCallerForAllOperations="true" /> 
    </behavior>
  </serviceBehaviors>
</behaviors>
 <bindings>
  <basicHttpBinding>
    <binding name="httpBinding" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service behaviorConfiguration="MetadataBehavior" name="<serviceName>">
    <endpoint address="/" binding="basicHttpBinding" contract="<service contract>" bindingConfiguration="httpBinding"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    <host>
      <baseAddresses>
        <add baseAddress="<service url>"/>
      </baseAddresses>
    </host>
  </service>
</services>

I get error:

The contract operation 'method name' requires Windows identity for automatic impersonation. A Windows identity that represents the caller is not provided by binding ('BasicHttpBinding','http://tempuri.org/') for contract 'contract name','http://tempuri.org/'.

That is expected as the user credentials are not specified anywhere. The question is: Where should I place the credentials? Placing them in system.web/identity doesn't work. I think that WCF needs them to be configured separately. Where?

2

2 Answers

1
votes

Another way to get the Windows identity of the current caller like this:

var identity = ServiceSecurityContext.Current.WindowsIdentity;

Also, according to this MSDN page, your binding needs BasicHttpSecurityMode to be set to TransportWithMessageCredential

0
votes

Eventually it seems that impersonating WCF method execution can be done only if ASPNET Compatibility is enabled:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

After enabling compatibility mode standard impersonation from system.web/identity works:

  <system.web>
        <authorization>
            <allow users="?"/>
        </authorization>
        <authentication mode="Windows"/>
        <identity impersonate="true" userName="mydomain\myuser" password="mypass"/>
  </system.web>

This solution is not suitable for more sophisticated bindings and requires the WCF implemetation class be decorated with

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

So it is not suitable for every case, but for me it was acceptable.