7

I need some help, I'm trying to pass windows credentials to a WCF service. In the IIS only Windows authentication is enabled for those service and runs over https.

The server side config is:

<system.serviceModel>
<protocolMapping>
  <add scheme="https" binding="basicHttpBinding" bindingConfiguration="httpsBinding"/>
</protocolMapping>
<bindings>
  <basicHttpBinding>
    <binding name="httpsBinding">
      <security mode="Transport">
        <transport clientCredentialType="Windows"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />          
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>

and in the client side:

<system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_IMyService" maxBufferPoolSize="2147483647"
      maxReceivedMessageSize="2147483647">
      <security mode="Transport">
        <transport clientCredentialType="Windows" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="https://myserver.net:4343/MyService.svc"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService"
    contract="MyServiceReference.IMyService" name="BasicHttpBinding_IMyService" />
</client>

I'm trying to consume the service on this way:

Client = new MyServiceClient();
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.MaxBufferPoolSize = long.MaxValue;
binding.MaxBufferSize = int.MaxValue;

EndpointAddress ep = new EndpointAddress("https://myserver.net:4343/MyService.svc");
Client = new COMINTSServiceClient(binding, ep);
Client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Identification;
Client.ClientCredentials.Windows.ClientCredential =  System.Net.CredentialCache.DefaultNetworkCredentials;
Client.Open();
Array[] obj = Client.RandomMethod();

This code doesn't work for me:

    Client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Identification;
    Client.ClientCredentials.Windows.ClientCredential =  System.Net.CredentialCache.DefaultNetworkCredentials;

In the service when ask for the user who is calling to the service using ServiceSecurityContext.Current.WindowsIdentity.Name allways get: ISS APPPOOL\ASP.NET v4.0 instead of the domain\user who is calling


The only way to make it work is write the username and password instead DefaultNetworkCredentials.

Client.ClientCredentials.Windows.ClientCredential.UserName = "DOMAIN\\user";
Client.ClientCredentials.Windows.ClientCredential.Password = "passw";

But I don't want a user/passw hardcoded. Any help please?

dina
  • 111
  • 1
  • 2
  • 9

2 Answers2

2

Try:

Client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

Keep the assignment from CredentialCache.

toadflakz
  • 7,764
  • 1
  • 27
  • 40
  • thanks @toadflakz but doesn't work for me. if I'm not mistaken, I can not use TransportCredentialOnly with an https service. If I try to call the open method get an "the URI scheme https is not valid" exception – dina Feb 05 '16 at 11:54
  • Did you try the `AllowedImpersonationLevel`value? – toadflakz Feb 05 '16 at 12:04
  • yes @toadflakz, in my desperation I tried all the possibilities of the enumerated but allways received at service the ISS APPPOOL\ASP.NET v4.0 user instead that the current domain user who make the request – dina Feb 05 '16 at 12:29
  • Have you tried setting the `ChannelFactory` credentials rather than the `ClientCredentials`? i.e. `Client.ChannelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;` – toadflakz Feb 05 '16 at 13:22
  • same user (the ISS APPPOOL\ASP.NET v4.0), @toadflakz my code now is: `Client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; Client.ChannelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials; Client.ClientCredentials.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;` – dina Feb 08 '16 at 08:06
  • Back to basics then - is your IIS hosting site/server setup to handle Windows Authentication? It's strange that you're getting the IIS AppPool user consistently... – toadflakz Feb 08 '16 at 09:08
  • Yes, only Windows Authentication is enabled (Negotiate and NTLM providers), I'm asking for user using `ServiceSecurityContext.Current.WindowsIdentity` It is correct? – dina Feb 08 '16 at 09:12
  • Yes, that's correct. Have you got an entry similar to `` in your `web.config`? – toadflakz Feb 08 '16 at 09:20
  • Yes, but without the `` – dina Feb 08 '16 at 09:25
  • this was the key – dina Feb 08 '16 at 11:25
0

I faced with similar issue - "ServiceSecurityContext.Current.WindowsIdentity.Name" on the server side returned wrong username, not Current Windows User on the client side. Turns out "Client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials" may get credentials from Windows Credential Manager: enter image description here

I failed to find a solution to instruct WCF to avoid grabbing credentials from that storage. The workaround was to check if some credentials are stored for that IP address and remove them. I used "https://www.nuget.org/packages/CredentialManagement" for checking and removing. Here is the code:

            var creds = new Credential();
            creds.Type = CredentialType.DomainPassword;
            creds.Target = address.Uri.Host;//address is WCF EndpointAddress
            if (creds.Load() && creds.Username != System.Security.Principal.WindowsIdentity.GetCurrent().Name)
            {
                creds.Delete();
            }
uzrgm
  • 375
  • 3
  • 8
  • I recommend you create a new post as a question giving your specific issue. You posted your "similar situation" as an answer here, which will not be useful to you - as you will not likely get any info from the community regarding how to solve your issue. – qxotk Oct 24 '22 at 23:52