Sometimes you have to wonder why the most basic features are missing in a v1 product…
Imagine this scenario: You have a public facing web service. You want the widest possible reach and compatibility – so the perfect technologies for that are HTTP, SSL and basic authentication (usernames and passwords) – and your customer accounts are no Windows accounts.
There was no sane way to pull this off in WCF v1 (besides fiddling around with the HTTP pipeline and simulating the basic auth handshake – but that tied you to IIS/ASP.NET).
You may say now – isn’t that exactly what TransportWithMessageCredential is supposed to do? Not exactly – because this involves sending a basic WS-Security SOAP header inside of the message. I want simple HTTP basic auth….
(Christian and me had this very scenario at a customer just a few weeks ago…)
The good news is that WCF in .NET 3.5 will finally support this!
How does that work?
a) use transport security (e.g. basicHttpBinding)
<bindings> <basicHttpBinding> <binding name="secureBasic"> <security mode="Transport"> <transport clientCredentialType="Basic" /> </security> </binding> </basicHttpBinding> </bindings>
b) write a username/password validator
public class CustomUsernamePasswordValidator : UserNamePasswordValidator { public override void Validate(string userName, string password) { if (!AuthenticateUser(userName, password)) throw new SecurityTokenValidationException("..."); } }
c) hook up the validator in a serviceCredentials behavior
<behaviors> <serviceBehaviors> <behavior name="userName"> <serviceCredentials> <userNameAuthentication customUserNamePasswordValidatorType="..." userNamePasswordValidationMode="Custom" /> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors>
d) send a username/password using the client proxy
ChannelFactory<IService> cf = new ChannelFactory<IService>("Service"); cf.Credentials.UserName.UserName = "bob"; cf.Credentials.UserName.Password = "foo"; IService proxy = cf.CreateChannel(); Console.WriteLine(proxy.Ping()); ((IClientChannel)proxy).Close();
Pingback: Send username and password in clear text to web service over HTTP | BlogoSfera
I am trying this with IIS hosting where in IIS the only Anonymous authentication is enabled. When I run, I get:
The service ‘/DacsaServer/TestService.svc’ cannot be activated due to an exception during compilation. The exception message is: The authentication schemes configured on the host (‘Anonymous’) do not allow those configured on the binding ‘BasicHttpsBinding’ (‘Basic’). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly
Hey John did you ever have any luck resolving this?