Custom UserNamePassword Validators in .Net Framework 3.5


In the version of WCF that shipped with .Net Framework 3.0 we didn’t support custom validators with transport level HTTP security. We received much feedback from the community that this was a highly desired feature, so I’m happy to say we added support for this scenario in the 3.5 release of the .Net Framework.


Note that this is only supported under self hosted services.


Here is what you’ll need to do to get it to work:


1. Create your validator:

namespace Sample
{
using System.ServiceModel;
using System.IdentityModel.Selectors;
using System.ServiceModel.Security;

public class CustomUserNameValidator : UserNamePasswordValidator
{
// This method validates users. It allows in two users, test1 and test2
// with passwords 1tset and 2tset respectively.
// This code is for illustration purposes only and
// must not be used in a production environment because it is not secure.
public override void Validate(string userName, string password)
{
if (null == userName || null == password)
{
throw new ArgumentNullException();
}

if (!(userName == “test1” && password == “1tset”) && !(userName == “test2” && password == “2tset”))
{
throw new SecurityTokenException(“Unknown Username or Incorrect Password”);
}
}
}
}


 2. Configure your service; you’ll want to use Transport security and Basic clientCredentialType, this way the authentication header will be protected by SSL.


Configuration for the binding and behavior:

<bindings>
<wsHttpBinding>
<binding name=”BasicAuthentication”>
<security mode=”Transport”>
<transport clientCredentialType=”Basic” />
</security>
</binding>
</wsHttpBinding>
</bindings>

<behaviors>
<serviceBehaviors>
<behavior name=”CustomUserNamePassword”>
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode=”Custom”
customUserNamePasswordValidatorType=”Sample.CustomUserNameValidator, assemblyName”/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>


You can also add the custom validator through code:

host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator();
host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;


 

Comments (3)

  1. Pedro Felix says:

    Hello.

    I’m using a custom validator with the "web programming model" (WebServiceHost, …).

    However, when an exception is thrown in the Validate method, the resulting HTTP response contains a "403-Forbidden" status code. Shouldn’t this be a "401-Authorized" so that the user-agent requests another username and password from the user?

  2. I’ve had scattered posts in the past talking about the messaging features and enhancements in Orcas.

  3. Phil Henning has written about creating a custom username/password validator for HTTP , which is another