While this post assumes a C# web site, the steps will work for VB.NET just as well, but the syntax of the glue code will have to be adjusted slightly.
Because ASP.NET MVC changes frequently, this will be a high-level outline of what you must do to support OpenID, and the implementation details I will leave up to you and your particular version of MVC. At the end I will show the code that makes the whole thing work as of the most recent version of MVC at the time of writing.
- Download DotNetOpenId and extract the DotNetOpenId.dll found in the bin directory of the download.
- Add a reference to that assembly from your ASP.NET MVC web site.
- Create or open the controller that will login users. I will assume this controller is called "UserController". Create two actions: Login and Authenticate.
- Login will just display the Login view.
- Authenticate will respond to two requests: the form submission of your visitor who is logging in, and the OpenID Provider response after the redirect.
- Your controller should look something like this:
public class UserController : Controller { public void Login() { // Stage 1: display login form to user RenderView("Login"); } public void Authenticate() { var openid = new OpenIdRelyingParty(); if (openid.Response == null) { // Stage 2: user submitting Identifier openid.CreateRequest(Request.Form["openid_identifier"]).RedirectToProvider(); } else { // Stage 3: OpenID Provider sending assertion response switch (openid.Response.Status) { case AuthenticationStatus.Authenticated: FormsAuthentication.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, false); break; case AuthenticationStatus.Canceled: ViewData["Message"] = "Canceled at provider"; RenderView("Login"); break; case AuthenticationStatus.Failed: ViewData["Message"] = openid.Response.Exception.Message; RenderView("Login"); break; } } } }
- Create just one view: for the Login action you created. The Authenticate action does not need a view as it will only redirect the user to other URLs. The content of it should resemble this:
<% if (ViewData["Message"] != null) { %> <div style="border: solid 1px red"> <%= Html.Encode(ViewData["Message"].ToString())%> </div> <% } %> <p>You must log in before entering the Members Area: </p> <form action="Authenticate?ReturnUrl=<%=HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]) %>" method="post"> <label for="openid_identifier">OpenID: </label> <input id="openid_identifier" name="openid_identifier" size="40" /> <input type="submit" value="Login" /> </form>
- Adjust FormsAuthentication to use your Login action.
And that's pretty much it. Of course you'll want to customize the code to fit what you're specifically trying to do, but this code is all you need to get OpenId authentication going. I might add: getting OpenId authentication going securely, since there seems to be a rash recently of "cheap" OpenID implementations out there that try to implement just part of the spec and end up with insecure implementations. This method uses the DotNetOpenId library, which has had a lot more effort to a secure and complete implementation of OpenId 1.x and 2.0.
By the way, I'm new to the MVC framework, so if you have comments on how this code can be made better or prettier, I'm all ears.
[22Apr08 Update: Check out a follow-up post that builds on this sample to pull registration data from the OpenID Provider]
8 comments: