WCF TransportCredentialsOnly Configuration

by Rob Cooke 7. September 2010 05:18

For future self-reference (mostly)…

WCF in Framework 3.5 allows you to use a custom user name / password based authentication mechanism to authenticate individual service requests. This is nice.

This functionality (as with seemingly everything else in WCF) involves a tiny amount of code and a ton of configuration. This is less nice.

Note: These steps just allow you to do pretty much the most primitive authentication. Everything sent is still in the clear. So for the love of all things pure (and some that are not) don’t use this in production without with some kind of encryption.

That said, here’s how to set it up…

First, create a class deriving from System.IdentityModel.Selectors.UserNamePasswordValidator. Note, you’ll have to add a reference to System.IdentityModel.dll not System.IdentityModel.Selectors.dll. The SecurityTokenValidationException is in System.IdentityModel.Tokens.

using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using NDL.Data;

namespace NDL.DataService
{
    public class BasicAuthenticationValidator : UserNamePasswordValidator
    {
        private static UserDataManager mUserDataManager;

        /// <summary>
        /// Performs static initialization for the BasicAuthenticationValidator.
        /// </summary>
        static BasicAuthenticationValidator()
        {
            mUserDataManager = XmlDataManager.Instance.UserDataManager;
        }

        /// <summary>
        /// Performs validation using the given user name and password.
        /// </summary>
        /// <param name="userName">The user name supplied.</param>
        /// <param name="password">The password supplied.</param>
        public override void Validate(string userName, string password)
        {
            //Let the lower layer handle the authentication.
            if (mUserDataManager.AuthenticateUser(userName, password) == false)
            {
                throw new SecurityTokenValidationException("Authentication failed.");
            }
        }
    }
}

With the easy part out of the way, you now have to set up the service’s configuration to start using it.

In the binding section on both the server and client, modify the security configuration to enable TransportCredentialsOnly security mode.

<security mode="TransportCredentialOnly">
    <transport clientCredentialType="Basic" proxyCredentialType="None" realm="" />
    <message clientCredentialType="UserName" algorithmSuite="Default" />
</security>

Next, in the behavior section, set the validation mode and specify the type we created to handle the authentication.

<serviceCredentials>
    <userNameAuthentication 
        customUserNamePasswordValidatorType="NDL.DataService.BasicAuthenticationValidator,
 NDL.DataService" 
        userNamePasswordValidationMode="Custom"/>
</serviceCredentials>

Finally, you can set the credentials on the UserName property of the service client’s ClientCredentials property.

//Set up the service proxy.
DataServiceClient client = new DataServiceClient();
client.ClientCredentials.UserName.UserName = "user";
client.ClientCredentials.UserName.Password = "supersecret";

//Execute some service calls....
client.RetrieveCustomerList();

That’s it! I guess it’s really not that bad. (Ask me again in a few months when I’ve forgotten it all again…)

References:

Tags:

Been Busy!

by Rob Cooke 7. September 2010 05:13

The last month or so has been a bizarre whirlwind of real life for me. Here are some of the highlights:

  • Back to school
  • New team at work
  • More work at work
  • Apartment lease negotiations
  • Best friends moved across the country
  • New fitness cram plan
  • New personal projects
  • Turning 30…

With longer days, I’ve been pretty sapped by the time I have any free time and haven’t been able to write much. Hopefully, I’ll be able to break that cycle this week!

Tags:

Powered by BlogEngine.NET 1.6.1.0
Theme by Mads Kristensen | Modified by Mooglegiant