Configure mixed-authentication mode of Azure AD and ASP Identity for CMS 11

  • Updated

This topic suggests how to integrate both ASP Identity and Azure AD as methods of logging in Optimizely Content Management System (CMS) version 11. This also covers recent changes to Azure AD Graph API.

Before you start, complete setting up dependencies and Azure AD configurations; see Integrate Azure AD using OpenID Connect.
  1. Add ASP Identity support to CMS by configuring the Owin Startup class.
    app.AddCmsAspNetIdentity(); // Use cookie authentication 
    app.UseCookieAuthentication(new CookieAuthenticationOptions {
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/util/login.aspx"),
        Provider = new CookieAuthenticationProvider {
          // If the "/util/login.aspx" has been used for login otherwise you don't need it you can remove OnApplyRedirect. 
          OnApplyRedirect = cookieApplyRedirectContext = {
              app.CmsOnCookieApplyRedirect(cookieApplyRedirectContext, cookieApplyRedirectContext.OwinContext.Get  ());
            },
            // Enables the application to validate the security stamp when the user logs in. 
            // This is a security feature which is used when you change a password or add an external login to your account. 
            OnValidateIdentity = SecurityStampValidator.OnValidateIdentity <applicationusermanager, applicationuser="ApplicationUser"> (
              validateInterval: TimeSpan.FromMinutes(30),
              regenerateIdentity: (manager, user) = manager.GenerateUserIdentityAsync(user)
            )
        }
    });</applicationusermanager,>
  2. Declare cookie authentication type.
    // AuthenticationType needs to be the same as configured previously
    app.UseCookieAuthentication(new CookieAuthenticationOptions(
    { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie }
    ); app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ApplicationCookie);
  3. Add OpenIdConnectAuthenticationOptions.Scope and TokenValidationParameters.
    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
      ClientId = ...,
      Authority = ...",
      PostLogoutRedirectUri = ...,
      Scope = "openid email", // Add this
      TokenValidationParameters = new TokenValidationParameters
      {
        ValidateIssuer = false,
        RoleClaimType = ClaimTypes.Role,
        NameClaimType = ClaimTypes.Email // Add this
      },
    [...]
    
  4. Add claim data to SecurityTokenValidated event for CMS to correctly identify the username.
    [...]
    SecurityTokenValidated = (ctx) => 
    {
      // Configure ctx.AuthenticationTicket.Properties.RedirectUri as suggested...
      [...]
      // Add Claim for username data
      var identity = ctx.AuthenticationTicket.Identity;
      identity.AddClaim(new Claim(ClaimTypes.Name, identity.Name));
        
      //Sync user and the roles to Optimizely in the background
      ServiceLocator.Current.GetInstance<ISynchronizingUserService>().SynchronizeAsync(identity).GetAwaiter().GetResult(); // Change this
        
      return Task.FromResult(0);
    },
    [...]
    
  5. In Azure AD Dashboard:
    Go to App Registration > Select authentication app > API Permission > Add a permission > Microsoft Graph > Delegated permissions, click Add email, offline_access and openid > Grant admin consent for [AppName].

    Screenshot_.png

  6. Here is additional code as workarounds for common issues.
    // Works on non HTTPS connection
    app.UseContentApiIdentityOAuthAuthorization<ApplicationUserManager<ApplicationUser>, ApplicationUser>(new ContentApiOAuthOptions()
    {
      RequireSsl = false
    });
    // Fix hidden PII error
    Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
    // Fix antiforgery error
    System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;