Padarn: Dynamic Authentication

Our Padarn Web Server largely uses a subset of the IIS object model, so for many features and capabilities how you do things in IIS is paralleled in Padarn. Authentication follows that rule, but with a couple exceptions.

For good old-fashioned, built-into-the-browser Basic or Digest authentication it follows the same steps. Set the Authentication in your app.config file and the user will get a browser-provided authentication popup.

But what if we want to do authentication ourselves against our own user store? In this case Padarn has a few “custom” extensions to make things easier.

The first mechanism is to add users to the underlying user cache when you start up the Padarn Server. Something along these lines:

var server = new WebServer();
server.Configuration.Authentication.Users.Add(
    new OpenNETCF.Web.Configuration.User { Name = "username", Password = "password" }
);

You could also hard-code the user identities right into the app.config file.

This isn’t all that friendly, though – at least in my thinking. Another, more robust, way is to use Padarn’s AuthenticationCallback. This allows you to send a delegate into Padarn and have it call your customer authentication algorithm every time it needs to do authentication. It’s slightly more complex, but really it’s still not too terrible, and it supports Basic or Digest authentication.

// somewhere in startup
var server = new WebServer();
server.Configuration.Authentication.AuthenticationCallback = VerifyUsername;

...
// then somewhere else - in this case in the same class
bool VerifyUsername(IAuthenticationCallbackInfo info)
{
    // no username is invalid
    if (string.IsNullOrEmpty(info.UserName)) return false;

    // first do a lookup of the password - this might come from a database, file, etc
    string password = GetPasswordForUser(info.UserName);
    if (password == null) return false;

    // determine the authentication type
    var basic = info as BasicAuthInfo;
    if (basic != null)
    {
        // we're using basic auth
        return (basic.Password == password);
    }

    // it wasn't basic, so it must be digest (the only two supported options)
    var digest = info as DigestAuthInfo;
    // let the DigestAuthInfo check the password for us (it's hashed)
    return digest.MatchCredentials(password);
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s