0

I cannot seem to authorize service contract operations based on the credentials of the user who is calling my WCF service.

Service Web.Config

<system.serviceModel>
<services>
  <service name="WCFService.Service" behaviorConfiguration="DefaultServiceBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8080/WCFService"/>
      </baseAddresses>
    </host>                
    <!-- Net.Tcp EndPoints-->
    <endpoint address=""
              binding="netTcpBinding"
              contract="WCFService.IService"
              bindingConfiguration="NetTcp_Secured"/>
    <endpoint address="mex"
                binding="mexTcpBinding"
                contract="IMetadataExchange" />
  </service>
</services>
<bindings>
  <netTcpBinding>
      <binding name="NetTcp_Secured">
      <security mode="Transport">
        <message clientCredentialType="Windows" />
        <transport clientCredentialType="Windows"  protectionLevel="EncryptAndSign" />            
      </security>
    </binding>        
  </netTcpBinding>
</bindings>        
<behaviors>
  <serviceBehaviors>
    <behavior name="DefaultServiceBehavior">
      <serviceMetadata httpGetEnabled="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.serviceModel>

Client Web.Config

<system.serviceModel>
<behaviors>
  <endpointBehaviors>
    <behavior name="DefaultClientBehavior">
      <clientCredentials>
        <windows allowNtlm="true"
                 allowedImpersonationLevel="Delegation" />
        <httpDigest impersonationLevel="Impersonation"/>            
      </clientCredentials>
    </behavior>        
  </endpointBehaviors>      
</behaviors>    
<bindings>
  <netTcpBinding>
    <binding name="NetTcpBinding">                   
      <security mode="Transport">
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
        <message clientCredentialType="Windows"/>
      </security>         
    </binding>
  </netTcpBinding>
</bindings>    
<client>
  <endpoint 
    address="net.tcp://localhost:8080/WCFService/Service.svc"
    binding="netTcpBinding" 
    bindingConfiguration="NetTcpBinding"
    behaviorConfiguration="DefaultClientBehavior"        
    contract="TestWcfService.IService" 
    name="NetTcpBinding_IService">       
  </endpoint>
</client>           
</system.serviceModel>

Service Code...

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string GetCurrentPrinciple()
{
    return "Windows Identity: " + WindowsIdentity.GetCurrent().Name + " \\ " +
        "Thread Identity: " + System.Threading.Thread.CurrentPrincipal.Identity.Name;
}

I believe this is the reason why this attribute causes a security exception...

[PrincipalPermission(SecurityAction.Demand, Name = @"DOMAIN_NAME\User")]

The method can be called just fine across the service which makes me think that the security settings are ok. However, the above code, which runs in the service, always returns the name of the App Pool identity and not the identity of the user who called the service.

Doing the following in the immediate window of the service in a break point gives the following...

? WindowsIdentity.GetCurrent()
{System.Security.Principal.WindowsIdentity}
    AuthenticationType: "Negotiate"
    Groups: {System.Security.Principal.IdentityReferenceCollection}
    ImpersonationLevel: Impersonation
    IsAnonymous: false
    IsAuthenticated: true
    IsGuest: false
    IsSystem: false
    Name: "IIS APPPOOL\\DefaultAppPool"
    Owner: {S-1-5-SAME-AS-BELOW-}
    Token: 2300
    User: {S-1-5-SAME-AS-ABOVE-}

So I am authenticated - I just don't have the callers name!

Both service and client are set to Windows Authentication. If I do this in the client...

protected void Page_Load(object sender, EventArgs e)
{
    lblCurrentUser.Text =
        "Current Website User: " + HttpContext.Current.User.Identity.Name;
}

... it returns the correct domain and and username so I know the client has correctly ascertained my Windows credentials via the browser.

I am just not sure what I am missing here as to why the service does not report the client credentials.

Remotec
  • 10,304
  • 25
  • 105
  • 147

1 Answers1

0

you might need to set AllowedImpersonationLevel at the client level. Have look at these article - http://msdn.microsoft.com/en-us/library/ms731090.aspx http://blogs.msdn.com/b/asiatech/archive/2009/08/28/how-to-impersonate-or-delegate-a-client-in-wcf.aspx

vibhu
  • 1,657
  • 2
  • 15
  • 19
  • try to set AllowedImpersonationLevel to Delegation if service and clients are hosted on separate machine. If they are on same machine, then set it as Impersonation. See, if it works. – vibhu Aug 01 '13 at 12:41