arc1880
arc1880

Reputation: 519

WCF service not impersonating client

Logistics: 1 server running WCF service. 1 server running Database for the WCF service.

Question: I have a WCF service running on 1 server that connects to a separate server for the necessary data that it needs to retrieve. My issue is that when calling the service from a client machine, I get a database sql error stating that 'Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'. I believe I have set up the WCF service to use impersonation.

WCF Server Config:

<bindings>
  <ws2007HttpBinding>
    <binding maxReceivedMessageSize="214748">
      <security mode="Message">
        <transport clientCredentialType="Windows"
                   proxyCredentialType="Windows" realm="" />
        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                 algorithmSuite="Default" establishSecurityContext="true" />
      </security>
    </binding>
  </ws2007HttpBinding>
</bindings>
<services>
  <service behaviorConfiguration="Host.ServiceBehavior" name="Wcf.MyWebService">
    <endpoint address="" behaviorConfiguration=""
              binding="ws2007HttpBinding" contract="Wcf.MyWebServiceSoap">
      <identity>
        <servicePrincipalName value="ServerMachineName" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding"
              contract="IMetadataExchange" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="Host.ServiceBehavior">
      <serviceMetadata httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceAuthorization impersonateCallerForAllOperations="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

WCF Service Code:

public class MySebService: MyWebServiceSoap
{
   [OperationBehavior(Impersonation = ImpersonationOption.Required)]
   public string TestWebMethod()
   {
     DbDal dal = CreateDataAccessLayer();

     return dal.GetStringFromDatabase();
   }
}

Client Configuration and Code:

I'm programatically setting the following configuration items:

public void TestWebMethod()
{
  WS2007HttpBinding binding = new WS2007HttpBinding();
  EndpointAddress endpoint = new EndpointAddress("uri");
  ServiceClient client = new ServiceClient(binding, endpoint);
  client.ClientCredentials.Windows.AllowedImpersonationLevel =
                               TokenImpersonationLevel.Impersonation;
  client.ClientCredentials.Windows.AllowNtlm = true;
  string result = client.TestWebMethod();
  client.Close();
}

Upvotes: 2

Views: 1571

Answers (1)

Andrew Shepherd
Andrew Shepherd

Reputation: 45222

TokenImpersonationLevel.Impersonation allows the service to access resources local to the service, but does not allow the service to access external resources (for example, another service).

You must set the allowed impersonation level to TokenImpersonationLevel.Delegation.

client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Delegation;

Upvotes: 1

Related Questions