Search code examples
.netwcfwcf-bindingwcf-securityimpersonation

Access web.config settings using WCF Impersonation with net.tcp binding


I'm trying to use impersonation with my WCF service (using net.tcp binding) hosted in IIS 7. I've got to the point where it's impersonating the client but whenever I try to access any configuration settings in the web.config using Settings.Default.SomeSetting it throws a SettingsPropertyNotFoundException. Is this because IIS is running under a different identity to the impersonated identity? If so what settings must I change to allow them to run under the same impersonated identity? I've tried setting the "servicePrincipalName" property without any success.

I've included my web.config settings below:

<system.serviceModel>
    <services>
      <service name="TestServices">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="tcpbinding"
          contract="Test.ITestService">
          <identity>
            <servicePrincipalName value="NT AUTHORITY\NETWORK SERVICE" />
          </identity>
        </endpoint>
        <endpoint address="mextcp" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>        
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <bindings>          
      <netTcpBinding>
        <binding name="tcpbinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" portSharingEnabled="true">
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="None"/>
            <message clientCredentialType="Windows"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceAuthorization impersonateCallerForAllOperations="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Solution

  • It seems I wasn't properly impersonating my client on the server side as I needed to set the allowedImpersonationLevel on my client to "Impersonation". This defaults to "Identification". So when I tested using WindowsIdentity.GetCurrent().Name I got the correct user name but the user wasn't actually impersonated.

    So adding this to my client web.config did the trick:

        <client>
          <endpoint address="net.tcp://localhost/Test/Service/TestService.svc"
              binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ITestService"
              contract="ServiceReference.ITestService" name="NetTcpBinding_ITestService"
              behaviorConfiguration="ImpersonationBehavior">
          </endpoint>
        </client>
        <behaviors>
          <endpointBehaviors>
            <behavior name="ImpersonationBehavior">
              <clientCredentials>
                <windows allowedImpersonationLevel="Impersonation" />
              </clientCredentials>
            </behavior>
          </endpointBehaviors>
        </behaviors>