Just wanted to commit this to my memory and share it with others!
Mads Kristensen recently blogged about his ASP.NET Implementation of OpenId. It seems to be by far the simplest solution I've seen thus far.
http://blog.madskristensen.dk/post/OpenID-implementation-in-Csharp-and-ASPNET.aspx
Some links to help the search engines: -
ASP.NET OpenId
Open Id in ASP.NET
I'll let you know how I get on with it.
Thanks Mads, great work!
UPDATE
This works fantastically well, with a few additions I have it fully implemented inside an existing ASP.NET site: -
Custom Security Principal: -
using
System.Security.Principal;namespace Site.Code.BusinessLogic
{
public class OpenIdPrincipal : IPrincipal
{
public OpenIdPrincipal(IIdentity identity)
{
_identity = identity;
}
public OpenIdPrincipal(IIdentity identity, string[] roles)
{
_identity = identity;
_roles = new string[roles.Length];
roles.CopyTo(_roles, 0);
Array.Sort(_roles);
}
private IIdentity _identity;private string[] _roles;
// IPrincipal Implementationpublic bool IsInRole(string role)
{
return Array.BinarySearch( _roles, role ) >=0 ? true : false;
}
public IIdentity Identity
{
get
{
return _identity;
}
}
}
}
Global.asax.cs
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
//http://msdn2.microsoft.com/en-us/library/aa302401.aspx#secnetht06_step4string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];if (null == authCookie)
{
return;
}
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception ex)
{
return;
}
if (null == authTicket)
{
return;
}
// Create an Identity objectFormsIdentity id = new FormsIdentity(authTicket);if (id.Name.IndexOf("http://") == 0)
{
// This principal will flow throughout the request.Site.Code.BusinessLogic.OpenIdPrincipal principal = new Site.Code.BusinessLogic.OpenIdPrincipal(id);
Context.User = principal;
}
}
Then once we've got the data back from the OpenId provider: -
//Create the Authentication cookie and redirect the user to their home page
//http://msdn2.microsoft.com/en-us/library/aa302401.aspx#secnetht06_step4FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(data.Identity, false, 60);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName,encryptedTicket);
Response.Cookies.Add(authCookie);
Response.Redirect(
"~/Home.aspx");
Then if you need to support both normal user and the OpenId users you can use something like this: -
if (HttpContext.Current.User is OpenIdPrincipal)
{
//Response.Write("OpenId");
//Response.Write(HttpContext.Current.User.Identity.Name);
}
The ASP.NET Membership controls won't work with this - needs a custom provider which recognises the bits and bobs of OpenId.