Cannot get Azure WCF service to work with Client Certificates - wcf

I have a WCF service that I want to secure with Client Certificates but I cannot get it to work on Azure.
I removed Azure from the equation by hosting the service on a standard Windows Server on Amazon. I installed both the service and client certificates (none are self-signed) into the Local Machine 'Personal' store on this server including the chained certificates and it all worked as expected, called from my local PC, with the client cert set against the binding/behavior. It did not work without the certificate being specified so it definitely worked correctly this way.
I then deployed the service to Azure. The client and server certificates are uploaded to the portal and set in the config against "Local Machine/My" and the CA and root certificates are uploaded and I tried them in various stores including "My", "Trusted" and "CA". Every variation I try, I continue to get "The HTTP request was forbidden with client authentication scheme 'Anonymous'" called from exactly the same program locally with the only change being the client endpoint address.
As another detail, I can get it to work without certificates so there is no problem with the web service but I am unsure how to work out what is actually happening with the certificate handshake between client and service.

I have finally got it to work, and have written a guide here: Blogspot.co.uk
I'm not sure what I had got wrong before since I have not done anything too weird to make it work. I think perhaps I had a small defect somewhere in configuration that I eventually fixed by starting again. Anyway, it DOES work and provides some useful security on Azure.

See my answer to this SO post - bottom line, cert in LocalMachine/My and run with elevated privileges in csdef file add:
<Runtime executionContext="elevated" />

Related

Using ssl with localhost with asp.net mvc 5 on VS2015

I'm trying to test my website locally using SSL with IIS Express. It has the following properties set:
SSL Enabled set to 'true'
SSL URL is set https://localhost:44354/
But whenever I open the https address, I get the following error:
In "Microsoft Edge":
In Google Chrome:
I've read article after articles, including some on SO but to no avail. I've tried the following:
I've deleted my IIS Express Development Certificate
I've repaired IIS Express 10 via the Control Panel
I've removed the localhost certificate I had created manually.
I've added <binding protocol="https" bindingInformation="*:44354:localhost" /> to the bindings section the applicationhost.config
I've stopped and restarted IIS Express.
Some suggest to change the port to 443 but my SSL URL is read-only in .NET IDE.
Some articles I've read:
Running IIS Express without Administrative Privileges
How do I fix a missing IIS Express SSL Certificate?
IIS Express — Getting SSL to Work
and many more...
Any help would be greatly appreciated.
Thanks.
I finally figured it out by following this article How to trust the IIS Express Self-Signed Certificate but a few additional steps:
Export IIS Express Development certificate to a local from. This certificate can be found in the Server Certificates section in IIS 10.0.
Open the Certificate console by calling mmc.exe certmgr.msc from File|Run.
Delete all instances of localhost under the Trusted Root Certification Authorities|Certificates.
Import the newly created certificate. You will get prompted with the following:
Once imported, I went back to Asp.Net MVC 5 project, recompile it and ran it. When I ran it, I got prompted with the following:
This is when I knew I was on the right track as this was the first time I had ever seen this prompt! Click Yes, and now this prompt appears:
And click Yes on this prompt as well. Your project will then launch the relevant browser.
Go to the https address defined in your .net project, in my instance, https://localhost:44354/, and you will now see the padlock displayed in the address bar to indicate that it is a secure site:
Most of these answers were already available in different answers provided on SO but the points that were missing or that I missed were that I had to export my IIS Express Development certificate, delete all localhost entries (which I had done) and then re-import this certificate. Once done, .NET detects the change and you get prompted accordingly.
Anyway, I hope this will help others.
Self signed certificates need to be trusted or browsers won't accept them. You can easily use Jexus Manager to configure that,
https://www.jexusmanager.com/en/latest/tutorials/self-signed.html#to-trust-self-signed-certificate
While if you prefer manually, you can import the certificates to the Trusted Root Certificate Authority store in Windows.
Learn more about SSL, certificates, stores and so on (Google each of them and learn them thoroughly), so that next time you really understand what is the culprit before trying so many irrelevant things.
Jexus Manager also has an SSLDiag feature to identify potential issues,
https://www.jexusmanager.com/en/latest/tutorials/ssl-diagnostics.html
But you need to know enough so as to interpret its output correctly.

UCMA 5 NegotiateSecurityAssociation error when machine is not part of the domain

I'm making my first steps in the UCMA world. The samples Microsoft delivers as part of the SDK seem simple enough, but I've hit a snag. If I run any of them from my dev box, I get an AuthenticationException when establishing the UserEndpoint.
The message of the exception is "Unable to perform authentication of credentials". Drilling down to the inner exception, I see this
NegotiateSecurityAssociation failed, error: -2146893039
My Skype 4 Biz pool is in a different domain than my dev box (in fact the dev box is not domain joined), the Skype4B domain CA is trusted though so the error comes somewhere later than in the establishment of a TLS session (initially I got a TLS error since the CA wasn't trusted).
Reading through the SDK documentation, in the chapter about activating trusted applications it is stated that unless you intent to run the Skype4B commandlets or use UCMA auto-provisioning, the machine running the app does not need to be a domain member. So now I'm thoroughly confused.. the same code works in the domain, but doesn't work on my dev box. It can't be a firewall issue because I run some of the clients in my skype4b domain in the same subnet as my dev box.
So what could I be missing?
I'm guessing since you are talking about UserEndpoint's that you are just starting a simple user endpoint UCMA application and you are supplying the username/password to the UserEndpoint?
If that's the case then it's most likely the certificate presented by the Lync server is not trusted your non-domain joined machine. You will need to manually add the root certificate that the Lync Server is using into the trusted cert store on your non-domain joined machine. This is normally the root certificate used by the domain in general, which is why it works on domain joined machines as this certificate is added automatically.
Another test you should do is see if the Lync client runs and connects to the lync server from the non-domain joined machine. My guess is that it will not as it will have the same certificate problem.
The Lync client / UCMA application errors around certificate failures are really bad and hard to understand!

MSMQ failing to send over HTTPS

I have been trying to get my MSMQ to pass messages over HTTPS without success. All outgoing messages sit in a queue with status "Waiting to connect".
This is not the case for messages over HTTP, they are received without issue.
I've created a Certificate Authority on the receiving machine, downloaded the cert chain and CA cert, installing under Trusted Root (Local Computer and Current User profiles).
I then exported the CA cert and installed that on the sending machine (under TRCA - Local Computer and Current User)
I have been able to navigate to the target MSMQ using internet explorer, this usually give a 501 not implemented error.
I don't really know why this isn't working and it's pretty fraustrating.
What other approaches can I take to get this to work??
Cheers
Niall
The screenshot shows that the server isn't properly accepting the HTTPS connection from the client.
You'll need to add more information to your question, including details of how you attempted to bind the Server Authentication certificate to the endpoint on which your server is listening.

SSL with WCF not working! How to Debug

I am dabbling with WCF and SSL and have hit a bit of a problem.
I have a self-hosted WCF service and a basic client which connects to request a token.
I have it set up on my development machine it appears to communicating over SSL just fine.
But when I set it up on a different machine to test the deployment the client keeps getting nothing back from the service.
I assume it has something to do with the certificates I have set up as this is the only thing I think could be different.
I have used the netsh command to associate my port with an existing certificate that was already on the server. And it appears the same as my dev machine (where I created the certificate with makecert manually.
I initially tried to follow the same steps on the deployment server but failed as there was already a certificate with a common name of the server, so eve though the certificate generated when ever I tried to use the cert hash thumbprint of the newly generated certificate I was being given the :
SSL Certificate add failed, Error: 1312
A specified logon session does not exist...
The only way I could get the netsh http add to work was by specifying the cert hash of the existing certificate.
Is this my problem or a red herring? How do you debug issues like this?
Personally I just configure WCF tracing. It usually provides more user friendly info about a problem. Here's a how to link Configuring Tracing
Hope it helps!

WCF self-hosted service with transport security (Authentication failed because the remote party has closed the transport stream.)

I have a self-hosted service that I want to add transport security to.
I've set WSHttpBinding.SecurityMode to Transport and the ClientCredentialType to HttpClientCredentialType.None.
I've created a certificate and set it to my host with
ServiceHost.Credentials.ServiceCertificate.SetCertificate()
I've also registered it using
netsh http add sslcert ipport=127.0.0.1:80 certhash=[MyCertHash] certstorename=MY appid=[TheGuidOfTheAppTahtRunsTheService] verifyclientcertrevocation=disable
I'm getting the following error message whenever I try to call the service:
"Authentication failed because the remote party has closed the transport stream."
Does this mean the the client and server try to authenticate each other? How can I disable it?
To make things clear, I do not want to install a certificate at the client, I'm not looking for any authentication atm, just securing the messages content, if that's even possible.
This MSDN post may help solve your problem. The initial request in the post is to configure a different security mode than yours but they switch to Transport mode for troubleshooting and that info should apply to your situation.
If what you describe is all you've done to install the certificate then you're missing a few steps. The post outlines the process to get a valid certificate installed. Good luck!!
Certificates can be a pain in the ass some times to get working. First thing you should always do with WCF is turn on tracing:
http://msdn.microsoft.com/en-us/library/ms733025.aspx
Then, you can use SVCTraceViewer to view the exceptions that your service is generating behind the scenes and get a little insight into what is happening, which is a must with many WCF problems. 9 out of 10 times, the trace will tell you everything you need to know.
Also, make sure that both the client and the server have the certificate configured, since the certificate needs to be installed on both machines.
I was trying to track down this same error, and came across this post. WCF tracing doesn't help as the error appears on the client side in the HTTP stack, and on the server side the request is rejected before it ever makes it to the WCF layer.
I found that I wasn't being thorough enough. Make sure all the following conditions are met. I had some but not all of these properly set up:
The server's certificate issuer has a valid and matching issuing
trusted root CA on the same machine.
The server certificate subject name matches the machine name
exactly, and the machine name the client is accessing matches as well ("localhost" vs the server's Environment.MachineName value)
The server certificate's thumbprint
has been set by an Administrator
using the following command (use
netsh equivalent for newer versions of Windows)
httpcfg set ssl -i 0.0.0.0:{port} -h {thumbprint}
This client also has the same valid issuing root CA certificate on the client machine.
Here's a good reference: SSL with Self-hosted WCF Service.