Windows Live ID – Part 3 – Putting it all together

In the previous two articles I showed you how to use the Windows Live ID login control in your web site then we developed a custom Membership provider so that you could hook Windows Live ID in with asp.net’s build in user management features. This article will show you it’s easy to hook these things together.

A lot of the code you in this article should be familiar to you by now, it really is just a case of hooking them together.

The first thing you’ll need to do is create the database structure, stored procedures etc. that the provider model expects. This is easily accomplished by running the aspnet_regsql wizard which is found in c:windowsmicrosoft.netframeworkv2.0.50727.

We will use our existing web site that we created in the first article. So open that up and then open up your web.config file. There are a couple of things we need to add to this, namely the connection string to your database and the membership provider (you should already have the appSettings that contains your secret and appID from the first article.  Since we also used the Microsoft Enterprise library for database access in the membership provider, we need to add that as well.

So in your web.config file you should have a configSections that looks like the following :-

 <configSections>

    <section name=dataConfiguration type=Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a />

    <sectionGroup name=system.web.extensions type=System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35>

      <sectionGroup name=scripting type=System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35>

        <section name=scriptResourceHandler type=System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 requirePermission=false allowDefinition=MachineToApplication />

        <sectionGroup name=webServices type=System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35>

          <section name=jsonSerialization type=System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 requirePermission=false allowDefinition=Everywhere />

          <section name=profileService type=System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 requirePermission=false allowDefinition=MachineToApplication />

          <section name=authenticationService type=System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 requirePermission=false allowDefinition=MachineToApplication />

        </sectionGroup>

      </sectionGroup>

    </sectionGroup>

  </configSections>

Most of this is for Microsoft ASP.Net Ajax support but notice the top entry, this is the entry for the enterprise library.
Below your configSections you need to add a dataConfiguration tag like this :-

<dataConfiguration defaultDatabase=Connection String />

This simply points to your database connection string which should be coded as normal :-

<connectionStrings>

    <add name=Connection String connectionString=Data Source=YourServer;Initial Catalog=LiveID;Persist Security Info=True;User ID=userid;Password=pwd

      providerName=System.Data.SqlClient />

  </connectionStrings>

Just incase you haven’t already got it in your web.config file from the first part of this article, add an appsettings section and in there put in your secret and appID (see first article for more details) :-

  <appSettings >

    <add key=secret value=YourSecret/>

    <add key=appid value=000000000000000/>

  </appSettings>

  <system.web>

Finally we need to add a reference to our membership provider and also tell our web site that we will be using forms based authentication :-

    <membership defaultProvider=LiveIDMembershipProvider>

      <providers>

        <add description=Custom Membership provider connecting to central datastore connectionStringName=Connection String name=LiveIDMembershipProvider type=Hackersoft.UserRepository.LiveIDMembershipProvider/>

      </providers>

    </membership>

  <authentication mode=Forms/>

Here we’re just saying use our custom membership provider. Our membership provider will be using the same database connection string as the Enterprise library (infact it does use the enterprise library) and we set our web site to forms authentication. And that’s all the changes we need to make to our web.config file.

In your website, add the LiveIDMembershipProvider from the second part of this series into the App_Code directory. Also make sure you have added the appropriate enterise library dll’s and the WindowsLiveAuthLite.dll into your bin directory (see previous articles for more details on this).

So now we are ready for our site. This will be a short demonstration containing two pages, the default page contains the Windows Live ID login control and a label that we’ll use to display messages. If you have already registered with the site, then after you sign in using the Windows Live ID control, the label on this page will display a welcome message, if you have not registered then you will be redirected to another page where we will collect some information from you. In this demo we will collect the least amount of information necessary, an email address.

First off our default page :-

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>
<%@ Register Assembly=”AjaxControlToolkit” Namespace=”AjaxControlToolkit” TagPrefix=”AjaxToolkit” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN” “http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head runat=”server”>
    <title>Windows ID Login Page</title>
</head>
<body>
    <iframe id=”AuthLite” name=”AuthLite”
        src=”http://login.live-int.com/controls/webauth.htm?appid=<%=AppID %>&context=<%=context %>”
        width=”100px” height=”30px” marginwidth=”15″ marginheight=”5″
        frameborder=”0″ scrolling=”no” style=”border-style: solid; border-width: thin;”>
    </iframe>
    <form id=”form1″ runat=”server”>
        <asp:ScriptManager ID=”ScriptManager1″ runat=”server” />
        <div>
                    <asp:Label ID=”txt” runat=”server” />
        </div>
        <div id=”WelcomeMessage” runat=”server”>
                    <asp:Label ID=”Welcome” runat=”server” />
        </div>
    </form>
</body>
</html>

This page simply contains the Windows Live ID login component contained within the iFrame and our Label control.
The corresponding code behind page should mostly look familiar to you :-

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using WindowsLiveAuthLite;

using System.Web.Profile;

using Hackersoft.UserRepository;

 

public partial class _Default : System.Web.UI.Page

{

  protected string AppID;

  protected string context;

  private string userid;

  private LiveIDMembershipProvider mem = new LiveIDMembershipProvider();

 

  protected void Page_Load(object sender, EventArgs e)

  {

    WindowsLiveLogin wll = new WindowsLiveLogin();

    AppID = wll.AppId;

    context = “Register.aspx”;

 

    HttpRequest req = HttpContext.Current.Request;

    string action = req.QueryString.Get(“action”);

    if (action == “clearcookie”)

    {

      byte[] content;

      string type;

      wll.GetClearCookieResponse(out type, out content);

      HttpResponse res = HttpContext.Current.Response;

      res.ContentType = type;

      res.OutputStream.Write(content, 0, content.Length);

      res.End();

    }

    else

    {

      WindowsLiveLogin.User user = wll.ProcessLogin(req.Form);

      if (user != null)

      {

        userid = user.Id;

        //txt.Text = “Your ID = ” + user.Id;

        //txt.Text += “<br> IsSane = ” + user.IsSane();

        //txt.Text += “<br> Token = ” + user.Token.ToString();

        //txt.Text += “<br> Context = ” + user.Context.ToString();

        if (mem.ValidateUser(user.Id, user.Id, “LiveIDExample”))

        {

          MembershipUser memuser = mem.GetUser(user.Id, “LiveIDExample”, false);

          Welcome.Text = “Welcome back “ + memuser.Email;

        }

        else

        {

          Server.Transfer(user.Context.ToString() + “?ID=” + user.Id);

        }

      }

    }

  }

 

}

We add a couple of references in our “using” section, pointing to the namespaces for our custom membership provider and WindowsLiveAuthLite.
We declare a couple of variables, the AppID and context are used in the main .aspx page and therefore have to be declared as protected rather than private. and we create a private instance of our membership provider.
The Page Load event should look familiar to you so I won’t go into too many details here (for more information see part one of this series). The biggest change to the Page Load event can be found at the bottom :-

        if (mem.ValidateUser(user.Id, user.Id, “LiveIDExample”))

        {

          MembershipUser memuser = mem.GetUser(user.Id, “LiveIDExample”, false);

          Welcome.Text = “Welcome back “ + memuser.Email;

        }

        else

        {

          Server.Transfer(user.Context.ToString() + “?ID=” + user.Id);

        }

Here we try to validate the user using our custom membership provider. If the user validates then we display the welcome message. If the user does not validate then that means the user hasn’t registered with our site so we pass them through to our registration page. If you looked at the top of the Page Load event, we passed in a context of “Registration.aspx” to Windows Live ID. Here we simply transfer to this page passing through the unique user ID returned by the Windows Live ID control.  So our page now looks like this with simply the Windows Live ID control displayed when you first visit it :-

 

Our second page is our registration page. On this page I am simply asking the user for their Email address so I have a label, textbox and a submit button. You could of course ask the user for more information depending on what it is that you wish to capture for your sites use. :-

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Register.aspx.cs” Inherits=”Register” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
    <title>Untitled Page</title>
</head>
<body>
    <form id=”form1″ runat=”server”>
        <div id=”Registration” runat=”server”>
                    <span>Email Address:&nbsp;&nbsp;</span>
                    <asp:TextBox ID=”txtEmail” runat=”server” />
                    <br />
                    <asp:Button ID=”btnSubmit” runat=”Server” OnClick=”btnSubmit_Click” Text=”Register” />
        </div>

    </form>
</body>
</html>

Nothing fancy there. And the corresponding code behind file :-

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using Hackersoft.UserRepository;

using WindowsLiveAuthLite;

 

public partial class Register : System.Web.UI.Page

{

  protected string AppID;

  protected string context;

 

  protected void Page_Load(object sender, EventArgs e)

  {

 

  }

 

  protected void btnSubmit_Click(object sender, EventArgs e)

  {

    int status = 0;

    LiveIDMembershipProvider mem = new LiveIDMembershipProvider();

    MembershipUser user = null;

    user = mem.CreateUser(Request[“ID”].ToString(), Request[“ID”].ToString(), “LiveIDExample”, txtEmail.Text, string.Empty, string.Empty, out status);

    //Response.Redirect(“Default.aspx”);

  }

}

Again nothing fancy. All we are dealing with is the button click event. In the button click event we create a new instance of our membership provider then simply use the CreateUser method to create a new user in our databases. The CreateUser method was explained in more detail in the second part of this series. We’re simply passing in the ID returned to us by the Windows Live ID control as the username and password, “LiveIDExample” is the Application Name.

And that’s basically it. If you go back to the Default page, we have a check in place to see if the user is a member and if they are we display a welcome message :-

The user is stored in the Asp.Net database and you can access it and use it just like you would normally, assign roles, profile information etc. etc.

Previously:
Windows Live ID – Part 2 – Membership Provider
Windows Live ID

The full code (minus passwords etc.) can be downloaded from here :-
Hackersoft Code Folder

 For those interested in further reading Kim Cameron has a few useful blogs up on her site :-
Yes or No?
Google’s Authentication versus Microsoft’s Live ID
Firefox support for Windows CardSpace