views:

1099

answers:

8

I have a web service (WCF or ASMX doesn't matter)... I have made a Console application, right-clicked, added service referrence. So far, so good.

However, I cannot for the life of me pass "security" credentials across to my service. This is my client code:

var client = new MyClient();

client.ClientCredentials.UserName.UserName = "bob";
client.ClientCredentials.UserName.Password = "123!!";

client.HelloWorld();

client.Close();

But on the server, no matter what I do (aspnetcompant mode on and off, wcf service, asmx service, custom http handlers, etc)... I can't find 'bob:123!!' anywhere. Not in headers, not in HttpContext.Current.User.Identiy.Name, not in Thread.CurrentPrincipal... nothing.

What am I missing here?

A: 

Have you configured the UserName (message security) or Basic (transport security) client credential type on the endpoint binding?

+2  A: 

Yes I have, and apparently if you don't use SSL, .Net throws an exception. So apparently you can't do what I want without SSL.

Timothy Khouri
With framework are you using? Some things changed for WCF/SSL in 3.5 (or SP1)
Marc Gravell
So you propose to pass usernames and passwords over the network, without encryption?
Calroth
Could be a VPN... you don't know :)
Timothy Khouri
I was annoyed by the same issue. It would be nice not to have to generate self-signed test certificates in development and testing, but have SSL on only for production. Oh well...
rally25rs
A: 

From what I understand, WCF does message level auth, not integrated auth. In either case, I'm not sure passing credentials is something you can do without SSL...

Have you tried turning on Anonymous authentication on the endpoint (via IIS)? From what I understand, WCF uses message level security (username/password passed in the message headers) rather than HTTP headers (used in integrated auth methods like Windows Integrated, SPNego, etc.)

some links I found...

Alice
A: 

If I understand your question correctly, you have succesfully configured username authentication for a WCF service (sorry - I'll focus on WCF) and you wish to gain access to the username and password within your serivce's methods.

You can access the username through ServiceSecurityContext.Current.PrimaryIdentity, I don't believe you can access the password easily.

One suggestion I found on the web, which I don't really like, is for your custom validator to keep a dictionary of username and passwords, which you could access later from your code given a username.

I don't like this for several reasons - one - you shouldn't really have access to passwords anyway, two - I'm not sure how secure this is, and three - if it's possible to have duplicate usernames (I know of some systems where this is the case) you might end up getting the wrong one.

Yossi Dahan
+4  A: 

Have you checked this article on custom validators: http://www.leastprivilege.com/FinallyUsernamesOverTransportAuthenticationInWCF.aspx?

Also, one thing that helped me when I worked on this was to disable anonymous access to that directory for the web server. HttpContext.Current.User.Identity.Name always returns an empty string when you are not authenticated. Thus it can look like you are authenticating correctly and just can't "find" the username, but really you are logged in anonymously. At least with anon access disabled, you will get an exception and can figure out the authentication side more easily, which is the hardest part.

nshaw
+1  A: 

See: http://developers.de/blogs/damir_dobric/archive/2006/07/31/890.aspx for information about TransportCredentialOnly to be able to pass usernames and passwords without SSL.

This should only be done in TESTING environments, as you are exposing the user's password in plain text.

divitiae
A: 

have you tried accessing this? (especially if you are using your own authentication system and your own UsernamePasssword and Certificate validators.

System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity.Name

you can get the caller's name but not the password.