0

I'm trying to set up a call to a secured HTTPS endpoint and establish SOAP based communication with the code below. I created a web service reference using Visual Studio and the service's WSDL.

//NetHttpsBinding binding = new NetHttpsBinding();
NetHttpsBinding binding = new NetHttpsBinding();

string url = "https://" + ...;
EndpointAddress address = new EndpointAddress(url);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//CustomClient client = new CustomClient();
CustomClient client = new CustomClient(binding, address);
client.ClientCredentials.UserName.UserName = "monkey";
client.ClientCredentials.UserName.Password = "donkey";

FindUsersByUserIdRequest request = new FindUsersByUserIdRequest
{
  applicationId = "kaweb",
  searchMatchMode = "EXACT",
  soughtUserId = "197002150485"
};

FindUsersByUserIdResponse response = client.FindUsersByUserId(request);
User[] result = response.users;

The computer doesn't like it and tells me something like this, with 401 specified. (Something because it's in a weird language we don't understand. And yes, there's a special corner of hell devoted for people who won't use English in coding because it's oh, gosh, so much easier to understand.)

System.ServiceModel.Security.MessageSecurityException:
Http request is not approved according to client schema Anonymous. Autentization header from server was Basic realm="CT".

When I check the available bindings, I see that I'm supposed to use NetHttpsBinding (because we work against HTTPS as stated by the URL). The authentication method is suggested here and I tried to roughly follow this approach.

The endpoint as such works and produces correct values, which I verify using SoapUI and basic authentication with the same set of credentials. Also, other people are claimed to be able to fetch the info, according to the general hintification (although I suspect then have Java based clients).

I've tried googling how to specify the authentication schema but failed to find relevant information (or was too ignorant to recognize when it was there). According to this suggestion I should manipulate the headers in the request. I don't seem to have that field accessible in FindUsersByUserIdRequest object though (and overriding it seems as a bad idea since it's auto-generated and I can't control it.

How do I do that and/or how can I troubleshoot it further?

sɐunıɔןɐqɐp
  • 3,332
  • 15
  • 36
  • 40
Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • When you use https and authentication is done with TLS before the request is sent. The version of TLS that you are using as the default may not work. You cannot use TLS 1.0/1.1 and must use TLS 1.2/1.3. See following : https://stackoverflow.com/questions/64375532/ssis-c-sharp-http-getasync-not-waiting-for-the-response#comment113835214_64375532 – jdweng Oct 23 '20 at 20:26
  • @jdweng Thanks for the hint. When you say *may not work*, it sounds like **one** of several possible issues. Is there are way I can validate/exclude that? – Konrad Viltersten Oct 23 '20 at 21:08
  • Older version of kernel (phones), operating system, net, may not support TLS 1.2/1.3. And the certificate encryption mode may not be supported in TLS 1.2/1.3. See : https://en.wikipedia.org/wiki/Transport_Layer_Security. – jdweng Oct 24 '20 at 03:08
  • @jdweng Regrettably, I don't seem to make it work. I used the `ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;` as suggested in the linked question placing it right before the instantiation of the client as shown in the updated question here. I'm not using `HttpClient`, though but rather `System.ServiceModel.ClientBase` autogenerated from the provided WSDL in the web service. That shouldn't matter, though, right? Do you have other suggestions on how to trouble-shoot this issue? – Konrad Viltersten Oct 26 '20 at 05:22
  • Also check this: https://stackoverflow.com/a/1712795/5311735 – Evk Oct 26 '20 at 06:01
  • @Evk It was `basicBinding` and `netBinding`. I reworded the code for ease of the readers. Corrected now. Also, see the update on your linked question. – Konrad Viltersten Oct 26 '20 at 06:26
  • If SoapUI works then next step I'd try is view raw request via fiddler from SoapUI and your app, and compare. – Evk Oct 26 '20 at 06:51
  • Use a sniffer like wireshark or fiddler. See if you get a response and check the status of the response which is normally 200 OK or an 400/500 error. If you do not get a response then the issue is probably TLS. The TLS will come before the request and the sniffer will show the version of TLS. TLS 1.0/1.1 is no longer accepted by servers and has to change. If TLS is 1.2/1.3 and failing then there is something wrong with the encryption. Either the certificate containing the key is not loaded in both client or server or the encryption mode is not compatible with 1.2/1.3 (old 1.0/1.1) – jdweng Oct 26 '20 at 08:15

1 Answers1

1

It looks like (from a bit of searching this error) you're missing a way of specifying the "realm" which you must do for the requests. You appear to be able to set this in the app-config.xml

eg1:

<basicHttpBinding>
   ...  
     <security mode="TransportCredentialOnly">
        <message clientCredentialType="UserName" algorithmSuite="Default"/>
        <transport clientCredentialType="Ntlm" proxyCredentialType ="Ntlm" realm="CT"/>
      </security>
    </binding>
   </basicHttpBinding>
   ...

eg2:

 <security mode="Transport">
   <transport clientCredentialType="Basic" proxyCredentialType="Basic" realm="CT">
      <extendedProtectionPolicy policyEnforcement="Never" />
   </transport>
   <message clientCredentialType="UserName" algorithmSuite="Default" />
 </security>

eg3:

<security mode="Transport">
   <transport clientCredentialType="Basic" proxyCredentialType="Basic" realm="CT" />
</security>

Although admittedly a bit of an "educated guess", let us know if this works as I can point out some potentially relevant answers if not.

Rob Evans
  • 2,822
  • 1
  • 9
  • 15
  • Someone else has beaten you to it but he's a local to our organization so he had unfair advantage. That said, out problem is still not getting the data **but** the connection is now established and if he hadn't glown with brilliance, your input would be the savior. So you're getting the bounty, unless something extraordinary happens before I'm allowed to award it. Feel urged to remind me in a day or two, too. You deserve it. – Konrad Viltersten Oct 27 '20 at 10:01