Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF username without certificate

I'm working on a project where I need the following.

  • WCF service on the server side (.NET 3.5)
  • WPF client for the client side (.NET 3.0)

I have an existing application that I have to use the authentication and authorization from (on the server side). I also need to store some metadata about the user in the WCF Service's Thread Principal (a site object). I do this so that I can get at it in the WCF service if I absolutely have to; some business logic may require it. So my plan was to do the following...

Create a custom ServiceAuthorizationManager for the server and in there I will log in the user and get the roles from the existing application. I will cache the "Site" object, and upon further reqests pull from the cache. I'll also need a CustomPrincipal object to hold my custom data. I want to impersonate the user so that I can use the builtin roles filtering in WCF like this:

[PrincipalPermission(SecurityAction.Demand, Role = "Role1")]
public string[] RolesForUser(string username){}

I attempted to use the ASP.NET authorization with a custom roles provider, but I wasn't able to set anything on the Current Principal. I also attempted to use a custom IAuthorizationPolicy, but problems arose. These problems dealt with being able to use the WCFClient.exe application, when it was discovering (using the mex endpoing) it wouldn't give any credentials, so the login would fail. I eventually decided that a ServiceAuthorizationManager was the right way to go, but I'm open to other suggestions.

On the client I will gather the credentials and put them into the WCF proxy class, as follows.

proxy.ChannelFactory.Credentials.UserName.UserName = userName;
proxy.ChannelFactory.Credentials.UserName.Password = password;

As I started to go down this route, I noticed that I wasn't able to get the username/password in the CheckAccessCore method of my manager class. Further investigation showed that I should really be authenticating in a custom UserNamePasswordValidator. So I created one of those. The problem is that the validate method never got called.

Further investigation showed that in order for the validate method to be called my WCF service has to have either message or transport level security. The problem with that is that I can't figure out how to have a message or transport level security without an X.509 certificate. This product is going into several hundred incredibly locked down machines, and installing a certificate is not possible.

Is there a way to do what I'm asking without installing a certificate?

like image 637
Joshua Avatar asked Dec 18 '08 22:12

Joshua


3 Answers

Actually it's possible, but you will need to implement your own binding.

Yaron Naveh developed a WCF binding that enables clear text username/password over HTTP. His article includes the code for the binding.

like image 143
jassuncao Avatar answered Nov 10 '22 04:11

jassuncao


Short answer; you can't. As soon as you use username/password you need some sort of secure channel.

However you don't need certificates on the clients; only on the server.

like image 31
blowdart Avatar answered Nov 10 '22 03:11

blowdart


I don't know the details of your network infrastructure, but if you are in a Windows domain, you should consider using Windows credentials.

It is possible to use a Message security without certificates if you use Windows credentials. This is the default behavior of the wsHttpBinding (out of the box).

Using the out-of-the-box solutions (without implementing your own binding) WCF encourage (requires) you to use a secure channel whenever authentication credentials are included in the messages.

Using a custom binding that allows you to specify credentials in clear text is surely a solution, but I would think twice before using it.

like image 1
xtrem Avatar answered Nov 10 '22 03:11

xtrem