Protecting an ASP.NET WebForms App with OpenId Connect and Azure AD
All of our official .NET samples that show some web UX are based on MVC. This caused somebody to speculate that the new OWIN components for OpenId Connect and WS-Federation require MVC to function. Nothing farther from the true! You can totally use those to secure your WebForms apps. Here there’s a super quick tutorial on how to do it. It is super easy. 98.8% of the tutorial is exactly the same of the corresponding MVC based tutorial, but for the sake of de-normalization I am going to go through those steps by value instead of by reference, on account of the possibility that some of you guys might not have had any previous exposure to this given the samples’ MVC bias.
Create an empty project
Fire up the good ol’ VS2013, and head to new project->ASP.NET Web application. On the project template dialog, pick Web Forms. Hit OK.
Visual Studio will create your project according to the template you picked. Before moving any further, let’s enable SSL.
- Select the project node in solution explorer. Hit F4.
- In the resulting property pages, flip SSL Enabled from false to true.
- Copy the newly populated SSL URL.
- Right click on the project node. Choose properties.
- Move to the Web tab. Paste the SSL Url in the Project Url field. Shift+CTR+S to save the new settings.
Provision the app in Azure AD
Let’s leave VS for few moments and pay a visit to the Azure portal, where we will tell to our Azure AD tenant about our newly minted application.
Navigate to https://manage.windowsazure.com/, sign in as your tenant admin, scroll to the Active Directory tab, choose the tenant you want to use, select the Applications tab, and click the Add button on the appbar at the bottom of the screen.
Choose “Add an application my organization is developing”.
Give to the app any name you like. Keep the default “web application and/or web api”. Click the Next arrow.
In the Sign-On URL enter the HTTPS address you got when you enabled SSL on the project (mine is https://localhost:44307/). In the App ID URI enter any valid URI that will later remind you of what this app is. For my test app I chose http://wifeistravellinghenceIblogoutofboredom. Click the Done button.
Click on the Configure tab and leave the browser open there. We’re going to need some of the values here in just a moment.
Add references to the Cookie/OpenId Connect/SystemWeb NuGets
Next, let’s go back to Visual Studio. Go to Tools->Library Package Manager->Package Manager Console. In the console, enter the following three magic commands:
Install-Package Microsoft.Owin.Security.OpenIdConnect -Pre
Install-Package Microsoft.Owin.Security.Cookies –Pre
Install-Package Microsoft.Owin.Host.SystemWeb –Pre
Those will bring down the Katana components you need.
Add the initialization logic
We are in good shape! Given that we started from the Individual Auth template, the OWIN pipeline is already present. We just need to change it to use OpenId Connect. If for some reason (e.g ADFS) you want to use WS-Federation, the mechanism is *exactly* the same, you just use the appropriate middleware.
- Go to the App_Start folder and open Startup.Auth.cs.
- Change the usings directives with the following:
using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.OpenIdConnect; using Owin;
- Next, change the body of ConfigureAuth to match the following:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions()); app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { ClientId = "d04fb01f-0715-4ed7-a656-0793b545e1f1", Authority = "https://login.windows.net/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e" });
That will change the pipeline to use OpenId Connect. The values you see there are associated to my test app: you will have to change those with the coordinates of your own app, in your own tenant. Namely:
- Go back to the portal. Scroll the app configuration page until you find Client ID. Copy the value. Come back to VS and paste the copied value in the string initializing ClientId
- In the string used to initialize Authority, substitute the GUID you see there with the domain of your tenant (e.g. myawesometenant.onmicrosoft.com).
Done.
Give it a spin!
Hit F5. Your page will come up. Click on the Log In link on the top right corner, which comes directly from the template bits.
On the right hand side, you’ll notice the OpenIdConnect button. Hit it.
You’ll see the familiar AAD authentication UX. Enter your test user.
And voila’! The user is signed in. Q.E.D.
Extra Credit
The sequence below does not leave the project in the cleanest possible state – my goal was to show you in the smallest number of steps that the OpenId Connect (and WSFederation) middleware does work with WebForms.
In a more realistic setup, you would likely start from a template with the “no authentication” option. That would leave you with the responsibility of adding Startup.CS, but that’s really boilerplate code. Also, you would likely want to add some automatic authentication trigger. That is easy enough to achieve. For example, consider the following implementation of Default.aspx.cs:
using Microsoft.Owin.Security; using Microsoft.Owin.Security.OpenIdConnect; using System; using System.Web; using System.Web.UI; namespace OWINandWebForms { public partial class _Default : Page { protected void Page_Load(object sender, EventArgs e) { if (!Request.IsAuthenticated) { HttpContext.Current.GetOwinContext().Authentication.Challenge( new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType); } } } }
That simply triggers a sign in in case the caller is not authenticated. Not hard at all ![]()
Well, there you have it. OpenId Connect, Azure AD and WebForms.
We chose OWIN as the platform for our new wave of identity libraries because of its flexibility – don’t let the fact that we standardized on MVC for our samples stop you from enjoying the latest and greatest ![]()
Vittorio who?
Vittorio Bertocci is a developer, speaker, published author, avid reader, troublemaker, foodie, Italian expat, and other things that would not be wise to mention here. This is Vittorio's personal blog. The views and opinions expressed here are his, and not those of his employer.
Follow @vibronet@vibronet
With all the outrage about fake news on Facebook, I feel my 2913 writeup is back en vogue :) medium.com/i-m-h-o/a-stra…
About 10 hours ago from Vittorio's Twitter via Twitter for iPhone
With all the outrage about fake news on Facebook, I feel my 2013 writeup is back en vogue :) medium.com/i-m-h-o/a-stra…
About 10 hours ago from Vittorio's Twitter via Twitter for iPhone
@trickyizzo yep. But the refresh token works across tenants and ADAL3 uses it automatically
About 4 days ago from Vittorio's Twitter via Twitter for iPhone
Ha! Twitter introduced the robot vomit® codes :) pic.twitter.com/TYd74s8SgR
About 4 days ago from Vittorio's Twitter via Twitter for iPhone
@mikelikesitalot ha, never knew! Did you find code introducing that delay?
About 4 days ago from Vittorio's Twitter via Twitter Web Client
Posts
- October 2016 (1)
- September 2016 (1)
- July 2016 (1)
- June 2016 (1)
- April 2016 (1)
- January 2016 (2)
- December 2015 (2)
- September 2015 (2)
- August 2015 (4)
- July 2015 (1)
- June 2015 (1)
- May 2015 (2)
- April 2015 (1)
- March 2015 (3)
- February 2015 (4)
- January 2015 (1)
- November 2014 (4)
- October 2014 (5)
- September 2014 (4)
- August 2014 (2)
- July 2014 (8)
- June 2014 (1)
- May 2014 (4)
- April 2014 (4)
- March 2014 (6)
- February 2014 (5)
- January 2014 (1)
- December 2013 (4)
- November 2013 (2)
- October 2013 (9)
- September 2013 (3)
- August 2013 (3)
- July 2013 (5)
- June 2013 (8)
- May 2013 (4)
- April 2013 (17)
- March 2013 (16)
- February 2013 (6)
- January 2013 (4)
- December 2012 (3)
- November 2012 (5)
- October 2012 (1)
- August 2012 (3)
- July 2012 (6)
- June 2012 (9)
- April 2012 (1)
- March 2012 (7)
- February 2012 (1)
- December 2011 (1)
- November 2011 (1)
- October 2011 (2)
- September 2011 (1)
- August 2011 (2)
- July 2011 (5)
- June 2011 (2)
- May 2011 (15)
- April 2011 (9)
- March 2011 (2)
- February 2011 (5)
- January 2011 (8)
- December 2010 (3)
- November 2010 (3)
- October 2010 (6)
- September 2010 (6)
- August 2010 (8)
- July 2010 (2)
- June 2010 (9)
- May 2010 (13)
- April 2010 (4)
- March 2010 (6)
- February 2010 (1)
- December 2009 (3)
- November 2009 (16)
- September 2009 (3)
- August 2009 (5)
- July 2009 (6)
- June 2009 (7)
- May 2009 (10)
- April 2009 (11)
- March 2009 (4)
- February 2009 (2)
- January 2009 (6)
- December 2008 (3)
- November 2008 (9)
- October 2008 (3)
- September 2008 (5)
- August 2008 (7)
- July 2008 (8)
- June 2008 (6)
- May 2008 (6)
- April 2008 (11)
- March 2008 (10)
- February 2008 (9)
- January 2008 (12)
- December 2007 (6)
- November 2007 (5)
- October 2007 (10)
- September 2007 (4)
- August 2007 (1)
- July 2007 (1)
- June 2007 (17)
- May 2007 (8)
- April 2007 (10)
- March 2007 (10)
- February 2007 (4)
- January 2007 (6)
- December 2006 (2)
- November 2006 (3)
- October 2006 (5)
- September 2006 (3)
- August 2006 (7)
- July 2006 (3)
- June 2006 (7)
- May 2006 (4)
- April 2006 (6)
- March 2006 (8)
- February 2006 (3)
- January 2006 (2)
- December 2005 (5)
- November 2005 (2)
- October 2005 (6)
- July 2005 (12)
- June 2005 (6)
- May 2005 (3)
- April 2005 (8)
- March 2005 (4)
- February 2005 (14)
- January 2005 (9)
- December 2004 (5)
- November 2004 (1)
- October 2004 (3)
- June 2004 (3)
- May 2004 (3)
- April 2004 (3)
- March 2004 (1)
- February 2004 (2)
- January 2004 (3)
- December 2003 (5)
- November 2003 (5)
- October 2003 (5)
- September 2003 (5)
- July 2003 (2)
- June 2003 (4)
- May 2003 (1)
- April 2003 (9)






