Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
This topic provides an introduction to using OpenID Connect to integrate with Azure Active Directory. OpenID Connect is an authentication protocol built on top of OAuth 2.0 that can be used to securely sign users into web applications. This document shows how an Episerver application can use the OpenID Connect to sign-in users from a single/multi-tenant environment, using the ASP.Net OpenID Connect OWIN middleware.
For more information about how the protocols works, refer to Authentication Scenarios for Azure AD and Integrate Azure AD into a web application using OpenID Connect.
If you require role-based access control, refer to Adding application roles in Azure Active Directory
Disable the built-in Role and Membership providers in web.config:
<authentication mode="None" />
<membership>
<providers>
<clear/>
</providers>
</membership>
<roleManager enabled="false">
<providers>
<clear/>
</providers>
</roleManager>
Enable claims on virtual roles by setting the addClaims property. Also add the provider for security entities, which is used by the set access rights dialog and impersonating users. The SynchronizingRolesSecurityEntityProvider configured in the following example is using the SynchronizingUserService
<episerver.framework>
<securityEntity>
<providers>
<add name="SynchronizingProvider" type ="EPiServer.Security.SynchronizingRolesSecurityEntityProvider, EPiServer"/>
</providers>
</securityEntity>
<virtualRoles addClaims="true">
//existing virtual roles
</virtualRoles>
Open Package Manager in Visual Studio and install the following packages:
Install-Package Microsoft.Owin.Security.Cookies
Install-Package Microsoft.Owin.Security.OpenIdConnect
Install-Package Microsoft.Owin.Host.SystemWeb
Update-Package Microsoft.IdentityModel.Protocol.Extensions -Safe
Note: Always use Microsoft.IdentityModel.Protocol.Extensions package version 1.0.2 or later. Previous versions contain a critical bug that might cause threads to hang.
To configure the OpenID Connect, add the following code in the startup class for OWIN middleware
using System;
using System.Configuration;
using System.Globalization;
using System.Threading.Tasks;
using System.Web;
using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Extensions;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Notifications;
using Microsoft.Owin.Security.OpenIdConnect;
using EPiServer.Security;
using EPiServer.ServiceLocation;
public class Startup
{
// <add key="ida:AADInstance" value="https://login.microsoftonline.com/{0}" />
private static readonly string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
// <add key="ida:ClientId" value="Client ID from Azure AD application" />
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
//<add key="ida:PostLogoutRedirectUri" value="https://the logout post uri/" />
private static readonly string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
private static string commonAuthority = String.Format(CultureInfo.InvariantCulture, aadInstance, "common/");
const string LogoutPath = "logout path";
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = commonAuthority,
PostLogoutRedirectUri = postLogoutRedirectUri,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = false,
RoleClaimType = ClaimTypes.Role
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Write(context.Exception.Message);
return Task.FromResult(0);
},
RedirectToIdentityProvider = context =>
{
// Here you can change the return uri based on multisite
HandleMultiSitereturnUrl(context);
// To avoid a redirect loop to the federation server send 403
// when user is authenticated but does not have access
if (context.OwinContext.Response.StatusCode == 401 &&
context.OwinContext.Authentication.User.Identity.IsAuthenticated)
{
context.OwinContext.Response.StatusCode = 403;
context.HandleResponse();
}
return Task.FromResult(0);
},
SecurityTokenValidated = (ctx) =>
{
var redirectUri = new Uri(ctx.AuthenticationTicket.Properties.RedirectUri, UriKind.RelativeOrAbsolute);
if (redirectUri.IsAbsoluteUri)
{
ctx.AuthenticationTicket.Properties.RedirectUri = redirectUri.PathAndQuery;
}
//Sync user and the roles to EPiServer in the background
ServiceLocator.Current.GetInstance<ISynchronizingUserService>().
SynchronizeAsync(ctx.AuthenticationTicket.Identity);
return Task.FromResult(0);
}
}
});
app.UseStageMarker(PipelineStage.Authenticate);
app.Map(LogoutPath, map =>
{
map.Run(ctx =>
{
ctx.Authentication.SignOut();
return Task.FromResult(0);
});
});
}
private void HandleMultiSitereturnUrl(
RedirectToIdentityProviderNotification<Microsoft.IdentityModel.Protocols.OpenIdConnectMessage,
OpenIdConnectAuthenticationOptions> context)
{
// here you change the context.ProtocolMessage.RedirectUri to corresponding siteurl
// this is a sample of how to change redirecturi in the multi-tenant environment
if (context.ProtocolMessage.RedirectUri == null)
{
var currentUrl = EPiServer.Web.SiteDefinition.Current.SiteUrl;
context.ProtocolMessage.RedirectUri = new UriBuilder(
currentUrl.Scheme,
currentUrl.Host,
currentUrl.Port,
HttpContext.Current.Request.Url.AbsolutePath).ToString();
}
}
}
By default, you need to declare application roles in the Active Directory application, such as WebEditors, WebAdmins and etc. Either the application owner (developer of the app) or the global administrator of the developer’s directory can declare roles for an application.
This is an example of approles that declare WebAdmins and WebEditors. You can modify it according to your application roles. Be aware that you need to generate a new Guid for each role declaration.
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"description": "Editor can edit the site.",
"displayName": "WebEditors",
"id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"isEnabled": true,
"value": "WebEditors"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Admins can manage roles and perform all task actions.",
"displayName": "WebAdmins",
"id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX",
"isEnabled": true,
"value": "WebAdmins"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Admin the site.",
"displayName": "Administrators",
"id": "XXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX",
"isEnabled": true,
"value": "Administrators"
}
],
After declaring the approles, you need to upload the manifest to the Azure Active Directory application. Refer to Roles based access control for more information.
After a global administrator of the customer’s organization installs your application, either they or a user accounts administrator in their organization can assign users and groups to your application.
Last updated: Sep 16, 2016