Category Archives : Visual Studio


A lightweight implementation OWIN OAuth for ASP.NET Web Forms using Visual Studio 2013 – Part 3

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


A lightweight implementation OWIN OAuth for ASP.NET Web Forms using Visual Studio 2013 – Part 2 2

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.


Using the Dynamic Data Database Embedded Image Field Template

Introduction

Hi all.  I’ve been working with the old ASP.NET Dynamic Data website templates, as I wanted a quick and easy to use web UI for managing the data at http://rs-photography.org.

As the site is (obviously) image-centric, I wanted to make some modifications to the out-of-the-box Dynamic Data project to include native image rendering/loading and updating.

I thought this was going to be relatively straightforward, being that there is a NuGet packaging encouragingly called “Dynamic Data Database Embedded Image Field Template” as well as a package called “Microsoft.Web.DynamicData.Handlers” which promises “Asp.Net image handler for rendering images from database”.

image

image

image

The good news is that this is a relatively straightforward implementation, but sadly lacking in clear instructions once the packages are successfully added.  This post will clarify exactly what you must do to get images displaying in your Dynamic Data site.

Note: the only references I could find online were quite old (i.e. 2007-2008), and pre-dated the NuGet packages, hence I felt the need to write this article.

The Scenario – NuGet Packages installed

imageI’m going to assume that if you are reading this article, you’re familiar with Dynamic Data websites.  If you aren’t, I’d suggest you get up to speed by reading a couple of tutorials (e.g. this one) – it’s a synch to get a site built, takes only a couple of minutes.

Once you have your site loading correctly, you’ll need to ensure you have a column in a table which is of sql type “image”.  The Entity Framework models this (correctly) as a property of type byte array (byte[]).  By default, Dynamic Data templates don’t have a field template for the byte array type, so the column is ignored when scaffolding occurs.

Assuming you have the NuGet packages installed, you’ll automatically have two new field templates added to the DynamicData folder, like so (left).

Your web.config file will also be updated to include a http handler for image requests, like so:

<system.webServer>
    <handlers>
      <add name="ImageHandler" path="ImageHandler.ashx" verb="*" 
           type="Microsoft.Web.DynamicData.Handlers.ImageHandler"/> </handlers> </system.webServer>

The handler is implemented in a binary which is included in the project – Microsoft.Web.DynamicData.Handlers.

image

The Data Schema

Now, if you run up the site and drill into the table you’ve defined your image field in, you’ll probably notice the image column is missing.  As stated above, because of the data type, by default there’s no handler.  This is where you need to do some work to help the scaffolding and field templates map properly.

Here’s my table schema and entity definitions so you can see exactly what I’ve done:

The “Files” Table:

CREATE TABLE [dbo].[Files] (
    [FileId]       INT            IDENTITY (1, 1) NOT NULL,
    [Filename]     NVARCHAR (100) NULL,
    [CatalogId]    INT            NULL,
    [SizeId]       INT            NULL,
    [IsDefault]    BIT            DEFAULT ((0)) NOT NULL,
    [Height]       INT            NULL,
    [Width]        INT            NULL,
    [ImageData]    IMAGE          NULL,
    [HasImageData] BIT            CONSTRAINT [DF_Files_HasImageData] DEFAULT ((0)) NOT NULL,
    PRIMARY KEY CLUSTERED ([FileId] ASC),
    CONSTRAINT [FK_Files_Catalog] FOREIGN KEY ([CatalogId]) REFERENCES [dbo].[Catalog] ([CatalogId]),
    CONSTRAINT [FK_Files_Sizes] FOREIGN KEY ([SizeId]) REFERENCES [dbo].[Sizes] ([SizeId])
);

The File class (entity):

public partial class File
{
    public int FileId { get; set; }
    public string Filename { get; set; }
    public Nullable<int> CatalogId { get; set; }
    public Nullable<int> SizeId { get; set; }
    public bool IsDefault { get; set; }
    public Nullable<int> Height { get; set; }
    public Nullable<int> Width { get; set; }
    public byte[] ImageData { get; set; }
    public bool HasImageData { get; set; }
    
    public virtual Catalog Catalog { get; set; }
    public virtual Size Size { get; set; }
}

Adding Attributes

You’ll need to extend on the partial class(es) in your Entity Framework model.  You need to keep the column definitions the same, so you need to just extend the class for metadata purposes (i.e. attributes).  If you add the attributes directly to the generated classes, they’ll be overwritten when you refresh the data model.

To add the appropriate attributes, I did the following:

using System.ComponentModel.DataAnnotations;

 

[MetadataType(typeof(File_MD))] public partial class File { } public partial class File_MD { [ScaffoldColumn(true)] [UIHint("Image")] [ImageFormat(100, 100)] public byte[] ImageData { get; set; } }

Examining the Attributes – the important one is [UIHint] as this provides the scaffolding the name of the type template to use (suffix/prefixes are used automatically), ergo by specifying “Image” we are implying the use of Image.ascx or Image_Edit.ascx.  To learn more about how scaffolding works, check out the following MSDN article.

Note that the extended partial class must be in the same namespace as the data model.

Once we have these attributes in place, and reload the site – given a row that has data in the image column, we should see something more favourable:

image

Presto!  Nothing more to do.  We can also now use a file picker to upload an image for new and existing records:

image

..and here it is in the SQL table:

image

If you want to make your column naming a bit more pleasing, add the following attribute to the column definition (in your metadata extension):

[Display(Name=”Image”)] 

image

Summary

That’s it.  It comes down to getting the entity property attributes set properly, and the rest is easy as.  It’s essentially adding image handling support out of the box for Dynamic Data sites, the last part is something a NuGet package can’t do – which is to interpret your data model.

I’ve tested this with IIS Express, Visual Studio 2013 and SQL Server 2012 and Entity Framework v5 (the last version compatible with Dynamic Data sites).  Note that the Entity Framework v6 will not work with Dynamic Data sites due to the namespace refactoring.

Enjoy.

Useful Links

http://www.olegsych.com/2010/09/understanding-aspnet-dynamic-data-entity-templates/