Now that we have our application configured in Azure, we need to update the Startup.Auth.cs class (in the App_Start folder) so that the application can utilize Azure Active Directory authentication for the users. The Startup.Auth.cs class looks like this.
using System;
using System.IdentityModel.Claims;
using System.Threading.Tasks;
using System.Web;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Owin;
using BusinessApps.HelpDesk.Models;
using BusinessApps.HelpDesk.Helpers;
namespace BusinessApps.HelpDesk
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
ApplicationDbContext db = new ApplicationDbContext();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
OpenIdConnectAuthenticationOptions options = new OpenIdConnectAuthenticationOptions();
options.ClientId = SettingsHelper.ClientId;
options.Authority = SettingsHelper.AzureADAuthority;
options.PostLogoutRedirectUri = SettingsHelper.LogoutAuthority;
OpenIdConnectAuthenticationNotifications notifications = new OpenIdConnectAuthenticationNotifications();
notifications.AuthorizationCodeReceived = (context) =>
{
string code = context.Code;
AuthenticationHelper authHelper = new AuthenticationHelper();
String signInUserId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(SettingsHelper.AzureADAuthAuthority);
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), authHelper.GetClientAssertionCertificate(), null);
return Task.FromResult(0);
};
notifications.RedirectToIdentityProvider = (context) =>
{
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl + "/";
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
return Task.FromResult(0);
};
notifications.AuthenticationFailed = (context) =>
{
context.HandleResponse();
return Task.FromResult(0);
};
options.Notifications = notifications;
app.UseOpenIdConnectAuthentication(options);
}
}
}
Next, we can add an AuthenticationHelper class to the Helpers folder. This class will do the Azure authentication token management, and looks like this:
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace BusinessApps.HelpDesk.Helpers
{
public class AuthenticationHelper
{
public ClientAssertionCertificate GetClientAssertionCertificate()
{
X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = certStore.Certificates.Find(X509FindType.FindByThumbprint, SettingsHelper.CertThumbprint, false)[0];
ClientAssertionCertificate cac = new ClientAssertionCertificate(SettingsHelper.ClientId, cert);
return cac;
}
public async Task<AuthenticationResult> GetToken(string resource)
{
ClientAssertionCertificate cac = GetClientAssertionCertificate();
AuthenticationContext authContext = new AuthenticationContext(SettingsHelper.AzureADAuthority);
AuthenticationResult authResult = await authContext.AcquireTokenAsync(resource, cac);
return authResult;
}
}
}
Next, we’ll tell the application to define unique users by name. This can be accomplished by adding the following line of code to the Global.asax.cs file:
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
The entire Global.asax.cs file now looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace BusinessApps.HelpDesk
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
}
}
With any luck, if we run the application at this point, it will launch successfully:
Clicking Log In in the top right corner will take us to the Log In screen. Choose OpenIdConnect to login via Azure:
This takes us to the standard Azure login screen. Choose/Enter the organizational account, enter a password, and click Sign In (note the name of the application listed at the top of the login screen):
If all goes well, the application now knows who we are!
Pretty painless, right?
The Help Desk Demo
- The Help Desk demo, Part 1 – Creating the project
- The Help Desk demo, Part 2 – Azure Active Directory
- The Help Desk demo, Part 3 – Authentication
- The Help Desk demo, Part 4 – Microsoft Graph
- The Help Desk demo, Part 5 – SQL Azure
- The Help Desk demo, Part 6 – SharePoint
- The Help Desk demo, Part 7 – Wiring it all up
- The Help Desk demo, Part 8 – Deploying to Azure
The entire source code for the Help Desk demo can be found here https://github.com/OfficeDev/PnP/tree/dev/Solutions/BusinessApps.HelpDesk/, in the Office 365 Dev PnP GitHub repository.