Profile picture Schedule a Meeting
c a n d l a n d . n e t

OpenId Authentication In Castle Monorail with ExtremeSwank OpenID Consumer

Dusty Candland | |

I spent some time today setting up OpenId in Monorail using ExtremeSwank OpenId consumer library. I went with a view component that can be on every page and a login controller to handle the authenticate and logout functions. This code is mostly a mix of the ExtremeSwank sample code and monorail sample code and probably shouldn’t be used in a production environment.

Anyway, we’ll start with the controller. It has three methods, Index, Authenticate, and Logout. The Index is just an empty action to explain OpenId to those who may not have experience with it. Authenticate takes the OpenId URL provided by the user to authenticate.  We store that in the session and pass to the consumer. Then we call BeginAuth which will process the request as long as the URL is correct. If not I render the Index view.

public void Authenticate(string openIdUrl)
{
try { OpenIDConsumer consumer = new OpenIDConsumer();
consumer.Identity = openIdUrl;
Session[OPENID_LOGIN] = consumer.Identity;
consumer.ReturnURL = Context.UrlReferrer;
consumer.BeginAuth();
}
catch (Exception e)
{
PropertyBag["message"] = "Login attempt failed.";
}
RenderView("Index");
}

ly, I have the Logout method which just removes the OpenIdUser object from the session.

public void Logout()
{
Session[OPENID_USEROBJECT] = null;
RedirectToReferrer();
}

Next I have the ViewComponent which checks to see if the user is authenticating, authenticated, or not. I check for the OpenIDUser in the session first, if it finds that, then the user is authenticated. Otherwise, it creates a OpenIdConsumer object which looks at the state of authentication and executes accordingly, rendering either the default URL box or the logout link.

public override void Render()
{
OpenIDUser user = Session[LoginController.OPENID_USEROBJECT] as OpenIDUser;
if (user != null)
{
RenderLoggedIn(user);
}
else { OpenIDConsumer consumer = new OpenIDConsumer();
switch (consumer.RequestedMode)
{
case RequestedMode.IdResolution:
consumer.Identity = (string)Session[LoginController.OPENID_LOGIN];
if (consumer.Validate())
{
user = consumer.RetrieveUser();
Session[LoginController.OPENID_USEROBJECT] = user;
RenderLoggedIn(user);
}
else { RenderLoginFailed(); } break;
case RequestedMode.CancelledByUser:
RenderLoginCancelled();
break;
default:
base.Render();
break;
}
}
}

eded to add the appropriate views, but thats mostly all that's needed for this simple setup.

Webmentions

These are webmentions via the IndieWeb and webmention.io. Mention this post from your site: