CustomCertificateValidator not called when client certificates option is set to "accepted" on IIS - wcf

I have the following situation:
I am looking for the possibility to authenticate a user at a wcf rest service optionally by username/password or by certificate. I have 2 clients, one is using authentication via username/pw and the other one via certificate.
But the CustomCertificateValidator class like described here https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/how-to-create-a-service-that-employs-a-custom-certificate-validator is only called when the client certificates option unter SSL in IIS is set to "required", but I need it when set to "accepted" if I want to use the same service. Does anybody know I that doesnt work generally? What I am doing wrong? In my web.config I set the option
Regards, Jimmy

Regarding CustomCertificateValidator, you can download the wcf demo provided by the official document. After downloading, it is the WF_WCF_Samples folder. Go to WCF>Extensibility>Security>X509CertificateValidator. The X509CertificateValidator example shows how to use custom X509CertificateValidator to verify client credentials. The official document also provides detailed instructions for the use of demo.

Related

IIS Client Certificate Mapping Authentication - mapping not working

I am trying to setup IIS Client Certificate Mapping Authentication and so far I have been unsuccessful.
I have a valid client authentication certificate
I disabled all authentication methods in the Authentication feature of IIS for the target website
Using the configuration editor I setup iisClientCertificateMappingAuthentication as documented in various sources. In this series of screen we map a domain account to a certificate. This is done by exporting the certificate to a text file, removing the first and last line and making sure all is in one line.
The problem is as follows:
When I try browsing to a test page, browser correctly prompts for selection of a certificate. I select the correct certificate. I then get presented with
HTTP Error 401.2 - Unauthorized
You are not authorized to view this page due to invalid authentication headers.
If I enable Anonymous Authentication then it works, but the user is not the one in the mapping it is the user running the browser. I know this because the test page contains the following:
response.write (request.servervariables("LOGON_USER"))
response.write (request.servervariables("AUTH_USER"))
So the questions are:
For IIS Client Certificate Mapping Authentication, is this the only authentication feature that needs to be enabled?
Do we need to use the Authorisation feature to limit the users to the one provided in the mapping?
What I am trying to achieve is that only clients that have the certificate will be able to access the service.
What am I missing?
Cheers
Jose

Simplest way to secure Azure Web Role WCF service

Using latest VS 2013 and Azure SDK 2.4, I've created a Web Role and a WCF service in it.
This service will be consumed by a standard generated .NET service reference client proxy.
I am trying to figure out what is the simplest way to secure this WCF service. I mean securing the authentication can not be hacked easy way, like clear text pwd etc.
Some additional info about the use case:
There will be only one user
It is completely OK to store any secret in client side (like username/pwd or certificate) because the client app will run in a secured place
I just would like to prevent my service to be accessed by the public. Only my secured place running client app should access it, I would like no more no less.
So I am googling the web, and more I read more I confused and overwhelmed with the options and possibilities what I do not need I think. When searching for client certificate I find overcomplicated federated auth methods with server side temp certs etc what I am not sure my simple use case requires.
Any help appreciated.
Thanks in advance
If you really want to restrict access then I would look at client certificates. Configuring azure for client certificates seems quite complex to detail in a single SO post so I'll refer you to this blog post client-certificates-in-windows-azure and I'll summarize below [I used this myself recently so I know it works]
In essence you can make your own certificates using makecert [NOTE: you may want an official SSL cert for your site and only use self-signed for your client certificates.]
You then configure your site to accept client certs - normally I'd use appcmd.exe and a startup task but as the blog post points out your site is not ready so instead you need to add this to your webrole OnStart method [I actually went down the appcmd.exe path initially and was very confused].
using (var serverManager = new ServerManager())
{
try
{
var siteName = RoleEnvironment.CurrentRoleInstance.Id + "_Web";
var config = serverManager.GetApplicationHostConfiguration();
var accessSection = config.GetSection("system.webServer/security/access", siteName);
accessSection["sslFlags"] = #"SslNegotiateCert";
serverManager.CommitChanges();
}
catch (Exception ex)
{
...
}
}
In the CertificateAuthHandler you can than validate the certificate and if you want (and I recommend) that the client certificate being sent is from your expected CA (if self-signed) or that the thumbprint of the certificate is the one you expect (if there is only going to be one) or a combination of the above.

Secure WCF service, what sort of authentication needed in addition to SSL protocol?

I have a server with SSL certificate and would like to implement a WCF service with username authentication. Can anyone point me to a simple current example?
I find lots that use the 509 certificate and I don't understand why that additional piece would be needed. I don't think I want to give the certificate I have for the SSL to the client either.
I think to use SSL is just setting up the web.config appropriately with wshttpbinding and using https: in the uri that calls the service.
In this case I will have only one or two users (applications at the client actually) that need to use the service so I don't see the overhead for building a database for the store for lots of login credentials or anything like that. I've read you can pass the credentials in the request header. I hope I can just have the service itself check them without tons of overhead.
I'm really struggling to get how a simple authenticate can work for a service but I know I need something in addition to the service being SSL encrypted.
Edit: Hummm having read more I get the impression that using https binding for the message circumvents any notion of username credentials without something mysterious with certificates going on. I hope I haven't wasted money on the ssl certificate for the server at this point.
Can the IP of the requestor be used to allow the service for a known client only?
If you only need a couple of users, then use the inbuilt Windows authentication - create Windows user accounts, put the right security option in your binding config and you're done. If you're using SOAP from a non-windows client you'll have to perform some tricks to make it communicate properly (typically we found using NTLM authentication from PHP client required the use of curl rather than the PHP SOAP client library, but I understand that if you use AD accounts this becomes much easier).
WCF docs have a full description of auth options for you.

How to configure SSL socket for the javax.xml.ws.Service?

I have a tomcat application that invokes an IIS hosted ssl enabled, client auth enabled Webservice
This Tomcat application talks to multiple wenservices and probably each of them require client auth along with PKI authentication.
For the IIS Webservice the wsdl url can change hence I use
javax.xml.ws.Service(url,qname) constructor by passing the url for the wsdl ...
The thing is I need to call the above with SSL with custom client key. How to I tell the above constructor to use a sslsocket that I create with my custom KeyManager ? I do not want to use
HttpsURLConnection.setDefaultSSLSocketFactory as that will enforce other outgoing ssl connection to follow to my keymanager which is exclusive to the IIS webservice.
Thanks for your reply.
If you follow the answer to your similar question on ServerFault and make sure that Tomcat's <Connectors /> don't use the javax.net.ssl properties, setting your keystore for the default key manager might not be the end of the world. HttpsURLConnections will only authenticate with it to server that ask for it (client-certificate authentication is always requested by the server) and that ask for a client-cert from a CA list that would match your certificate's issuer. This might not be such a big problem in practice.
If you think it's too big a problem, there seems to be an undocumented property called com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory. Its documentation is as follows:
Set this property on the BindingProvider.getRequestContext() to enable
HttpsURLConnection.setSSLSocketFactory(SSLSocketFactory). The property
is set as follows:
SSLSocketFactory sslFactory = ...; Map ctxt =
((BindingProvider)proxy).getRequestContext();
ctxt.put(SSL_SOCKET_FACTORY, sslFactory);
THIS PROPERTY IS EXPERIMENTAL AND IS SUBJECT TO CHANGE WITHOUT NOTICE
IN FUTURE.

Custom authentication in wcf without certificate, https, ssl and iis

First of all sorry for my English, its not my native language. I will try to describe my problem as much as I can.
I searched for a long time on the Internet for a solution where I can create a wcf service that can respond to requests of my clients with username and password required but without creating a certificate, using https or anything else that require a special configuration on the machine where my windows service will be installed.
Here is my point: I want to deploy an application to a lot of my customers. This application will have mobile devices and a server which will give some information to mobile device with the help of wcf. Each customer will have a server and many devices. I don't want that anyone on the web can have access to these information and for this reason, I must implement an authentication procedure with username and password for each request but I don't want to be forced to install a certificate, activate some https port on each machine when I sell a new copy of my application.
I've read that with wcf 4.0, there is a built-in system that can encrypt data and for this reason, I don't want the overhead of implementing anything else if possible.
My question is: Is that possible to have a secure solution considering my requirements and if yes, how can I do that?
If I really must create a certificate and use IIS, https or any other secure solution, it is possible to automate these things in a package that will be installed in a single click wizard into each server machine of my customers?
Thank you in advance for your time.
By default WCF doesnt allow transport of username credentials over http and hence have to use certificates to secure your transport layer. But if you are sure that you are fine with sending username credentials over the http channel then you can have a look at ClearUsernameBinding which gives you the flexibility of sending username credentials over http channel (consider the fact that someone can intercept your transport channel to get access to the credentials)
Also if you want to use certificates that have to be installed you can achieve that writing some code in c# and include that as part of your installation from your package. You can also configure everything from an msi like creating a virtual directory, deploying the application,etc..
what you are probably looking for is one of the wcf bindings that has message level security. You can put the user name and password into this message and not worry about them going across an http wire unencrypted(ie custom authentication). The defaults for WCF send user name and password as part of the http request in the header this is why it wants https.