Feb 132014
 

Introduction

In Part 1, we had a brief look at OWIN/OAuth concepts, and then prepared a clean ASP.NET web forms project for integration with NuGet packages essential to supporting a lightweight integration for OAuth handling.

In Part 2  we established the information required to authenticate users against the Live Connect OAuth provider, and also established a debugging environment; it’s time for the meat of the article.

Finally, this article will demonstrate the code necessary to handle authenticated user identities.  I must stress that this is incredibly lightweight, and hopefully it will be clear what you need to consider if taking this approach to a new or existing project.

Note: This article was originally published at Sanders Technology, check here for updates to this article and related technical articles.

The Concept Applied

Let’s quickly take a look at what you’ll be implementing from a conceptual point of view.  What you’ll be doing is effectively redirecting your users to a third party.  Once they have successfully authenticated, they’ll return to your site (or app) with some sort of token or claim (query string based).

Your site or app will then exchange this information with the third party to validate it is correct and valid.  If this is successful, the third party will share a bit of information about this user with you, which you could use to tie to a local identity if you preferred.

Here’s the concept in diagram form:

image
How the OAuth process works

Armed with this knowledge, there are a few design decisions you’ll need to make.  The most obvious one is planning how you’ll handle those redirects back to your site or application, once a user has authenticated with their OAuth provider (in this article, Microsoft Live Connect/Live Accounts).

In Part 2, I briefly discussed the importance of the Redirect Domain when configuring the Live Application.  This is, in fact, the target URL that your users will be given, once they’ve authenticated.  This can be a basic URI or a specific page.  In any case, the target has to be able to handle the authentication tokens.

Enough theory, show me some code

The code to handle authentication is ridiculously simple and lightweight.  In fact, I’ve encapsulated the logic into a single class.  In my example, I’ve hardcoded the implementation to the Microsoft provider, but I’m positive you could easily write a more generic implementation which accepts multiple OAuth providers.

This class handles the following functionality:

  • Initiate authentication (redirect to oAuth provider)
  • Handle and process authentication result (from redirect URL)
  • Save/store or cache authentication results (for subsequent requests)
  • Return basic user information (if authenticated)
  • Clear or expire authentication details

using DotNetOpenAuth.AspNet; using DotNetOpenAuth.AspNet.Clients; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace YourNamespace { public static class AuthenticationHelper { /// <summary> /// Determines if a user is presently authenticated /// </summary> /// <returns>True if authenticated, else false</returns> public static bool IsAuthenticated() { var auth = //TODO: Retrieve authentication information from temp local store or cache if (auth != null && auth.IsSuccessful) { //NOTE: Hard coded to the Microsoft provider string userName = OAuthDataProvider.Instance.GetUserNameFromOpenAuth("microsoft",

auth.ProviderUserId); //TODO: verify user id is a valid user return true; } return false; } /// <summary> /// Returns the user name for the currently authenticated user /// </summary> /// <returns></returns> public static string GetUserName() { var auth = //TODO: Retrieve authentication information from temp local store or cache if (auth != null) { return auth.UserName; } return String.Empty; } /// <summary> /// Verifies the authentication from the various OpenId and OAuth services,

///returns generic Authentication Result in res variable. /// </summary> /// <returns>Authentication information (can be null)</</returns> public static AuthenticationResult VerifyAuthentication() { var ms = new MicrosoftClient("<YOUR CLIENT ID>", "<YOUR SECRET KEY>"); var manager = new OpenAuthSecurityManager(new HttpContextWrapper(HttpContext.Current), ms, OAuthDataProvider.Instance); var result = manager.VerifyAuthentication("<YOUR REDIRECT URI>"); if (result != null) { //TODO: Save authentication information to temp local store or cache } return result; } /// <summary> /// Starts the authentication process. User will be redirected away from the current page /// </summary> public static void Authenticate() { var ms = new MicrosoftClient("<YOUR CLIENT ID>", "<YOUR SECRET KEY>"); new OpenAuthSecurityManager(new HttpContextWrapper(HttpContext.Current), ms, OAuthDataProvider.Instance)
.RequestAuthentication("<YOUR REDIRECT URI>"); } /// <summary> /// Used to “unauthenticate” an authenticated user /// </summary> public static void Unauthenticate() { //TODO: Clear authentication information from temp local store or cache } } }

Class diagram views follow:

image
Class diagram view of the Authentication Handler

There is an additional class required to make use of the OpenAuthSecurityManager class – a concrete class which implements the IOpenAuthDataProvider interface.  Luckily, you don’t have much to implement for this to work successfully:

using DotNetOpenAuth.AspNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication3
{
    public class OAuthDataProvider : IOpenAuthDataProvider
    {
        public readonly static IOpenAuthDataProvider Instance = new OAuthDataProvider();

        public string GetUserNameFromOpenAuth(string openAuthProvider, string openAuthId)
        {
            return openAuthId;
        }
    }
}

As you can see, I don’t even really do anything here, I’m just returning the provider-supplied value.  You could do much more with this, including your own application-specific formatting.

image

Class view of the OAuthDataProvider class

Taking a look at the runtime process

To illustrate how this all works, I’ve updated the “clean” example solution from Part 1.  I must stress, this is a very, very simple implementation, and should in no way be used in a Production website.  It’s simply to illustrate how lightweight the implementation can be.

The sample site has a master page with a simple user control on it.  This control reflects whether a user has authenticated or not, and provides a mechanism for initializing the authentication process (in short: a “login button).

I’ll now show you what the process looks like from a series of screenshots of the working solution.  In this example, I’ve made the modifications mentioned in Part 2, as I have aliased “atempuri.org” to my localhost (for debugging purposes).

I’ve also created a Live Application at the Live Connect site. Remember – you need the Client ID and Secret ID plus have set the correct Redirect URL for this to work.

The Process

To begin, I load the default page on the site.  Notice in the top left hand corner the fairly boring “[ Authenticate ]” button.  When I click the button, it redirects me to the Live Connect page to sign in with a Microsoft (formerly Live, formerly Passport) Account.

image    image
The default page / Authenticate to Microsoft

Once I have authenticated, the Microsoft site asks me to allow my application to access basic account data.

image
The user is prompted to authorise the application

Notice here that I have not supplied an application logo – doesn’t it look ugly and unprofessional?  Once the user clicks the “Yes” button, the Microsoft site redirects the user’s browser to the URI set in the Live Application’s settings – which must match the address specified in the code in your site or application.

In this case, the user’s browser is directed to http://atempuri.org/Login (with additional data in the query string).  My login.aspx page handles the request and checks that the user is not already authenticated.

image
The Login.aspx event hander code

This page forces the “VerifyAuthentication” call, and checks again OnPreRender to see if validation worked or not.  If it is successful, the user is redirected to the default page.

Below is an example of some of the information retrieved with a successful authentication:

image
Successful authentication provides very basic information

The ProviderUserId can be used to uniquely identify the authenticated user, and also provides a “friendly name” which you can use for display purposes.

image
We’ve achieved the Zen like state of “authenticated”

The default page now displays a more friendly user experience, and provides a mechanism for “logging off”.

More on the “TODO” elements of this approach

Again, I can’t stress strongly enough that this is only a simple proof of concept.  I’ve specifically cut corners here to demonstrate how little is needed to implement OAuth support for authentication.

If you look at the sample solution, there are three values you need to supply:

public static class AuthenticationHelper
{
      private const string KEYID = "<YOUR KEY>";
      private const string SECRET = "<YOUR SECRET KEY>";
      private const string REDIRECT = "http(s)://<YOUR REDIRECT URL>";
}

At a minimum you should consider doing the following with your own website or application, up-front:

  • Determine your complete security and identity requirements
  • Decide if you want  to have user profiles “local” to your application, and whether you’ll map these identities to their Provider ID
  • Consider an approach to storing or looking up the authentication data
  • Decide how your site or application should handle:
    • Unauthenticated users
    • Authenticated users
    • The location of your “Redirect URL”
  • Decide if you want to integrate this into the ASP.NET Role Provider
  • Consider using HTTPS/SSL for some or all of your site/application

That’s just a start, this barely scratches the surface.

Summary and Download

Well, I think I’ve managed to cover off all the basics of a lightweight implementation of OAuth (OWIN) using ASP.NET.  To aid you, I’ve attached a copy of the “clean” ASP.NET web forms solution, with the authentication classes and the user control included.  I’ve personally tested the solution with real Application keys and it is working as depicted here.

It’s not a bad start if you are just looking for a very lightweight way to integrate OAuth as a mechanism for identifying users, and could obviously be extended or used to integrate into your existing authentication/authorisation mechanisms.

If you’ve had any issues or have general feedback, shoot me an email: rob.sanders@sanderstechnology.com

Sample Solution

Feb 122014
 

Introduction

Where we left off in Part 1, we’d established the prerequisites to prepare either a new or existing web forms project for the implementation of a lightweight OWIN/OAuth provider.

This article, Part 2, will focus on how to prepare your development environment and also how to configure for Windows Live Account authorisation.

This article was first posted on Sanders Technology.  Check the site for updates to this article, and for more excellent technical articles.

Let’s start with the Live Application first:

Configuring the (Microsoft) Live Account Provider

You need to get two API keys in order to use the Microsoft OAuth interface.  To get the keys, you have to configure your application via the Live Connect Developer Center.

The first thing you’ll need is a Microsoft Account.  If you don’t have one, it’s easy enough to create one.  If you do already have an account, you just need to browse to http://msdn.microsoft.com/en-us/live to and sign in.

Click on “My apps” (https://account.live.com/developers/applications) from the menu:

image
Live.com – create application

You’ll want to then click on the “Create application” link, which will bring you to the introduction page.  Here you have to agree to the Ts and Cs and give your application (or website!) a name:

image
Create Windows Live application

Configure your Application

Once you have progressed, the site takes you directly to the API settings.  Notice the Client API key (Client ID) and Client secret key (Client secret) are already populated.  These are the two values you need for your site or application.

The key field you must complete here is the redirect domain.  This URL is critical and must match the endpoint that you wish to authenticate users from. 

The location must be able to handle the credentials returned from the Microsoft Live services.  If you aren’t sure what to use initially, you can come back and add it later.

image
Live application – API settings

If you like to do things properly, you should go to the Basic Information page and upload an application logo. 

When users first authenticate against your site or application they’ll be prompted to agree to share their identity with you. From this page, ensure you have copied the Client ID and the Client secret.

The page asking them to agree will show your application’s logo, so it’s best to have something nice and neat here.

image
Windows Live application – basic info

For completeness, I like to add links to privacy and terms of service policies, which you can do in the two fields provided.  They are optional.

That said, as long as you have the client key and client shared secret key, then you have everything you need for now.  Before you can go integrating Live OAuth, you’ll need to configure your development environment.

Configuring Visual Studio/Development Environment

Before you can integrate OAuth handlers into your solution, you’ll need to configure your environment so that you can debug and also so you can test the authentication process.  This is not as hard as you might suspect, since you have the client key and the shared secret key.

The first thing you’ll need to do is set up an entry in your HOSTS file to redirect your chosen domain to 127.0.0.1.  This means your outbound requests will go to your local host.   For example:

Open Notepad (with elevated permissions) and open the file “HOSTS” (no extension) which lives in sysdrive%:\Windows\System32\Drivers\etc

image
A local HOSTS file configured for contoso.org

image
A ICMP test (ping) showing contoso.org resolving to localhost (127.0.0.1)

IF you want to test out whether it has been set correctly, just jump to a console and try and ping the domain.  You should get responses as shown above.  Next, you need to configure your local development web server.

Configuring your Web Host

For this example, I’ll be configuring IIS Express for the task of hosting my requests.  You can also configure a local IIS service as well, but I’m not going to go into detail – for IIS, it’s a matter of configuring site bindings to add a HOST HEADER value.

IIS Express uses a set of configuration files, and they are conveniently located under your profile’s “My Documents”.  Here’s an example of where to find the applicationhost.config file:

image
Location of the IIS Express applicationhost.config file

Hint: It’s under your local profile’s directory.

Note: that after you have finished this step, you’ll need to launch Visual Studio with elevated permissions, or else IIS Express won’t be able to load your site.

In the file, locate the <sites> element, and then the site you wish to configure.

image

the key here is to add to the bindings collection for the site you are using.  As you can see from the above example, I’ve added contoso.org to the WebSite1 entry.  When IIS Express is launched, this binding will be applied, and since I have modified the HOSTS file, requests to contoso.org will be routed to IIS Express.

I recommend using port 80, as you need to give Live Connect a redirect URL which would work when live.  Naturally you can change URLs both with Live Connect and locally at any time.

Configure the Redirect domain

Now that you’ve gotten this far, you should be able to raise an instance of your site hosted in IIS Express, and the domain you’ve configured should resolve to the local server.  Note that if you are behind a proxy configuration, localhost and the domain should be added to the list of exclusions.

The domain you’re using should be configured appropriately in your Live Application, as mentioned earlier in this article.  The URL should match the URL you wish to authenticate OAuth tokens.  This can be HTTP or HTTPS based.

If you’ve gotten this far, you’re ready to implement the lightweight OWIN OAuth provider.  We’ll pick up on how to proceed in Part 3.

Summary

Apologies to those who have already accomplished the configuration mentioned here – however, I had to cover it off before I launched into the specifics of configuring the application implementation.  The last article in this series, Part 3, will focus entirely on implementing and testing integration with the Live OAuth provider.

Feb 062014
 

Introduction

Disclaimer: this article assumes the reader is already familiar with OWIN and OAuth standards.  It is published in three parts.

Late last year I wanted to implement Open Web Interface for .Net (OWIN) OAuth  functionality for an administrative subdomain.  As it happened, I wanted to specifically integrate OWIN/OAuth authentication/authorization for an existing Dynamic Data site (using the .NET Framework v4.5 and the Entity Framework v5) but to just authenticate using just the Microsoft API for Microsoft Accounts.

Unfortunately for me, the out-of-the-box (OOTB) ASP.net identity packages use an implicit local DB which, in turn,  uses the Entity Framework v6 – which is entirely incompatible with Dynamic Data templates (v4 and v5 only).

Therefore, I was left with only one option – strip the ASP.net Identity packages out altogether and write a lightweight implementation directly against OWIN/OAuth packages – essentially replacing the  Microsoft OOTB ASP.net packages and removing the local DB implementation altogether.

I’m pleased to say I managed to achieve this, and now I’m going to write about what I had to do to get the final result.  In the end I opted to use an alternative set of OWIN packages (DotNetOpenAuth.*) instead of the OOTB (Microsoft.Owin.*) packages – this is discussed further, below.

I’ll be referring to a clean OOTB web forms project (as a baseline) throughout, but the steps should apply equally to an existing web project.  Note that I haven’t explored the MVC/Web API avenue, but there might be some useful info here for non-web forms based ASP.NET sites as well.

Note: this article was originally published at Sanders Technology – check here for updates to this and related articles.

In this Article

The content for this concept will run across a couple of parts, since there’s much to do to get set up properly.  This current article, Part 1, will focus on establishing the requirements for running the lightweight implementationPart 2 will look at how to configure your development environment and Part 3 will focus on the actual implementation (and will assume you have read parts 1 & 2).

Basic Setup

What you ideally want to do is start with a new site.  If that’s not possible or if you just want to retrofit onto an existing project, then you could just add the necessary packages (via NuGet Package Manager) and extra implementation to your existing project – after all, this is meant to be a very light implementation.

To show the packages I’m adding and removing, I’ve created a brand new out of the box site using Visual Studio 2013, and will compare the vanilla packages.config against my intended configuration.

image
The New Project wizard

An out-of-the-box ASP.net web forms project (as per the above diagram) produces a packages.config with the following definition:

<?xml version="1.0" encoding="utf-8"?> 
<packages> 
  <package id="Antlr" version="3.4.1.9004" targetFramework="net45" /> 
  <package id="AspNet.ScriptManager.bootstrap" version="3.0.0" targetFramework="net45" /> 
  <package id="AspNet.ScriptManager.jQuery" version="1.10.2" targetFramework="net45" /> 
  <package id="bootstrap" version="3.0.0" targetFramework="net45" /> 
  <package id="EntityFramework" version="6.0.0" targetFramework="net45" /> 
  <package id="jQuery" version="1.10.2" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.FriendlyUrls" version="1.0.2" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.FriendlyUrls.Core" version="1.0.2" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.Identity.Core" version="1.0.0" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.Identity.EntityFramework" version="1.0.0" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.Identity.Owin" version="1.0.0" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.Providers.Core" version="1.2" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.ScriptManager.MSAjax" version="5.0.0" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.ScriptManager.WebForms" version="5.0.0" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.Web.Optimization" version="1.1.1" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.Web.Optimization.WebForms" version="1.1.1" targetFramework="net45" /> 
  <package id="Microsoft.Owin" version="2.0.0" targetFramework="net45" /> 
  <package id="Microsoft.Owin.Host.SystemWeb" version="2.0.0" targetFramework="net45" /> 
  <package id="Microsoft.Owin.Security" version="2.0.0" targetFramework="net45" /> 
  <package id="Microsoft.Owin.Security.Cookies" version="2.0.0" targetFramework="net45" /> 
  <package id="Microsoft.Owin.Security.Facebook" version="2.0.0" targetFramework="net45" /> 
  <package id="Microsoft.Owin.Security.Google" version="2.0.0" targetFramework="net45" /> 
  <package id="Microsoft.Owin.Security.MicrosoftAccount" version="2.0.0" targetFramework="net45" /> 
  <package id="Microsoft.Owin.Security.OAuth" version="2.0.0" targetFramework="net45" /> 
  <package id="Microsoft.Owin.Security.Twitter" version="2.0.0" targetFramework="net45" /> 
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" /> 
  <package id="Modernizr" version="2.6.2" targetFramework="net45" /> 
  <package id="Newtonsoft.Json" version="5.0.6" targetFramework="net45" /> 
  <package id="Owin" version="1.0" targetFramework="net45" /> 
  <package id="Respond" version="1.2.0" targetFramework="net45" /> 
  <package id="WebGrease" version="1.5.2" targetFramework="net45" /> 
</packages>

As mentioned in the introduction, you’ll notice that I’m using the “DotNetOpenAuth” packages created by Andrew Arnott which build upon the “DotNetOpenAuth extensions for ASP.NET (WebPages)” and “Microsoft WebPages OAuth library” which are built by Microsoft instead of the OOTB OWIN packages.  I was lead in that direction owing to the complicity of the OOTB packages, the DotNetOpenAuth implementation, IMHO, is much cleaner and easier to work with.

Note: I am referencing an updated version of the Entity Framework here (v6.0.2), in my earlier example site (mentioned in the introduction), I maintained the existing v5 version for compatibility with Dynamic Data templates.  The important point here is that the Entity Framework plays no part in implementing the lightweight OWIN/OAuth solution.

Below is the updated packages.config from my updated web forms website.

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Antlr" version="3.5.0.2" targetFramework="net45" />
  <package id="AspNet.ScriptManager.bootstrap" version="3.1.0" targetFramework="net45" />
  <package id="AspNet.ScriptManager.jQuery" version="2.1.0" targetFramework="net45" />
  <package id="bootstrap" version="3.1.0" targetFramework="net45" />
  <package id="DotNetOpenAuth.AspNet" version="4.3.4.13329" targetFramework="net45" />
  <package id="DotNetOpenAuth.Core" version="4.3.4.13329" targetFramework="net45" />
  <package id="DotNetOpenAuth.OAuth.Consumer" version="4.3.4.13329" targetFramework="net45" />
  <package id="DotNetOpenAuth.OAuth.Core" version="4.3.4.13329" targetFramework="net45" />
  <package id="DotNetOpenAuth.OpenId.Core" version="4.3.4.13329" targetFramework="net45" />
  <package id="DotNetOpenAuth.OpenId.RelyingParty" version="4.3.4.13329" targetFramework="net45" />
  <package id="EntityFramework" version="6.0.2" targetFramework="net45" />
  <package id="jQuery" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.FriendlyUrls" version="1.0.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.FriendlyUrls.Core" version="1.0.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.Providers.Core" version="2.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.Razor" version="3.1.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.ScriptManager.MSAjax" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.ScriptManager.WebForms" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.Web.Optimization" version="1.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.Web.Optimization.WebForms" version="1.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebPages" version="3.1.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebPages.Data" version="3.1.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebPages.OAuth" version="3.1.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebPages.WebData" version="3.1.0" targetFramework="net45" />
  <package id="Microsoft.Bcl" version="1.1.6" targetFramework="net45" />
  <package id="Microsoft.Bcl.Build" version="1.0.13" targetFramework="net45" />
  <package id="Microsoft.Net.Http" version="2.2.18" targetFramework="net45" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
  <package id="Modernizr" version="2.7.1" targetFramework="net45" />
  <package id="Newtonsoft.Json" version="6.0.1" targetFramework="net45" />
  <package id="Owin" version="1.0" targetFramework="net45" />
  <package id="Respond" version="1.3.0" targetFramework="net45" />
  <package id="WebGrease" version="1.6.0" targetFramework="net45" />
</packages>

Note: I’ve removed these packages:

  <package id=”Microsoft.AspNet.Identity.Core” version=”1.0.0″ targetFramework=”net45″ />
  <package id=”Microsoft.AspNet.Identity.EntityFramework” version=”1.0.0″ targetFramework=”net45″ />
  <package id=”Microsoft.AspNet.Identity.Owin” version=”1.0.0″ targetFramework=”net45″ />
  <package id=”Microsoft.Owin” version=”2.0.0″ targetFramework=”net45″ />
  <package id=”Microsoft.Owin.Host.SystemWeb” version=”2.0.0″ targetFramework=”net45″ />
  <package id=”Microsoft.Owin.Security” version=”2.0.0″ targetFramework=”net45″ />
  <package id=”Microsoft.Owin.Security.Facebook” version=”2.0.0″ targetFramework=”net45″ />
  <package id=”Microsoft.Owin.Security.Google” version=”2.0.0″ targetFramework=”net45″ />
  <package id=”Microsoft.Owin.Security.MicrosoftAccount” version=”2.0.0″ targetFramework=”net45″ />
  <package id=”Microsoft.Owin.Security.Twitter” version=”2.0.0″ targetFramework=”net45″ />

Remember – you also need to ensure that project references need to be removed as well, simply editing the packages.config won’t remove the old packages from your life!

image
Ensure these are removed, and that the new packages are referenced.

With the ASP.net Identity implementation removed, you’ll have to roll your own classes.  This is not as bad as it sounds.

Preparing a new ASP.net web forms project

This only applies if you’re intending on modifying a new project – skip to the next section if you want to integrate with an existing project.

To get this solution compiling (for an OOTB project), you’ll have to strip out the existing OWIN implementation, as the project won’t compile.

image

The following project artefacts would need to be deleted/removed:

  • Startup.cs
  • The entire Models folder
  • App_Start\Startup.Auth.cs
  • The entire Account folder
  • Remove “Unnamed_LoggingOut” function from Global.cs

You’ll also need to edit the Web.Config accordingly:

  • Remove “Microsoft.AspNet.Identity” from <namespaces>
  • Remove entity framework references (if not using the EF)
  • Remove the Membership, profile and roleManager elements

image

You’ll also need to edit the Site.Master to remove old Account artefacts:

<AnonymousTemplate>
    <ul class="nav navbar-nav navbar-right">
        <li><a runat="server" href="~/Account/Register">Register</a></li>
        <li><a runat="server" href="~/Account/Login">Log in</a></li>
    </ul>
</AnonymousTemplate>
<LoggedInTemplate>
    <ul class="nav navbar-nav navbar-right">
        <li><a runat="server" href="~/Account/Manage" title="Manage your account">Hello, 
<%: Context.User.Identity.GetUserName() %> !</a>
</li> <li> <asp:LoginStatus runat="server" LogoutAction="Redirect" LogoutText="Log off"
LogoutPageUrl="~/" OnLoggingOut="Unnamed_LoggingOut" /> </li> </ul>
</LoggedInTemplate>

You can just remove the parts in bold, and add your own implementation later.  You’ll also need to include the “Microsoft ASP.NET Razor” package and the “Microsoft ASP.NET Web Pages” package (if not already installed) and ensure a reference to the System.Web.WebPages.Razor assembly – as this is required by elements of the OWIN assemblies.

Once you get to this point your project should compile, but will it run?  If it doesn’t you might need to double check that you’ve removed all of the parts listed above. If everything’s been done correctly you should be able to compile and run (under IIS Express by default). If you want to save time, here’s a clean OOTB site which compiles:

Clean Solution

OWIN OAuth functionality – Prerequisites

Now I’m going to state up-front: this is a very lean implementation. The functionality stripped out from the OOTB website will not be replaced. Instead, you’ll be able to effectively “log in” to a site with an OpenId, e.g. a Microsoft account.  In other words – it’s up to you to decide what functionality to build around it.

To use OAuth, you’ll need to be familiar with the requirements of each OpenID provider you want to incorporate.

The ASP.NET examples are invariably Facebook, Twitter and Microsoft Accounts, but can be extended in theory to any OpenID provider.

I’ll be using Microsoft Accounts, since that’s what I’ve used in the past.  We’ll go into more detail about this in Part 2, which establishes the development environment and I’ll walk you through how to configure for Microsoft Accounts.  You’ll need this before going any further, or you won’t be able to test or debug.

For now though, ensure you have the following packages installed:

<package id="DotNetOpenAuth.AspNet" version="4.3.4.13329" targetFramework="net45" />
<package id="DotNetOpenAuth.Core" version="4.3.4.13329" targetFramework="net45" />
<package id="DotNetOpenAuth.OAuth.Consumer" version="4.3.4.13329" targetFramework="net45" />
<package id="DotNetOpenAuth.OAuth.Core" version="4.3.4.13329" targetFramework="net45" />
<package id="DotNetOpenAuth.OpenId.Core" version="4.3.4.13329" targetFramework="net45" />
<package id="DotNetOpenAuth.OpenId.RelyingParty" version="4.3.4.13329" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages.Data" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages.OAuth" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages.WebData" version="3.1.0" targetFramework="net45" />

..and we’ll cover off the specific implementation in Part 3.

Summary and Download

So this article really just establishes how to prime a clean web forms project, or what to do to prepare an existing web site project.  We’ve only just begun…  Part 2 will establish the environment and help you to configure the Microsoft Account provider.  Part 3 will walk through the basic implementation.

Clean Visual Studio Solution

Continue to Part 2.