Loading...
Area: Episerver Content Delivery API
Applies to versions: 2.9.0 and higher
Other versions:

Content Delivery API and Azure AD

Recommendations [hide]

This topic gives you an example of how to customize ContentDeliveryApi with an external login system like AzureAD.

First, set up a site using Episerver Azure AD. See Integrate Azure AD using OpenID Connect in the Episerver CMS Developer Guide.

Normally, the user information is synchronized with the website by calling ServiceLocator.Current.GetInstance<ISynchronizingUserService>.SynchronizeAsync(ctx.AuthenticationTicket.Identity) when using external login systems. In this case, because user information is not stored as the usual way, RoleService and UserService must be customized:

  • Create the class CustomUserService which inherits UserService. Override the function IsUserValid.
    [ServiceConfiguration(typeof(UserService))]
    public class CustomUserService : UserService
      {
        public CustomUserService(IContentAccessEvaluator accessEvaluator) : base(accessEvaluator)
          {
          }
        /// <summary>
        /// Check whether an user is valid
        /// </summary>
        public override bool IsUserValid(string name)
          {
            var synUserRepo = ServiceLocator.Current.GetInstance<ISynchronizedUsersRepository>();
            var users = synUserRepo.FindUsers(name);
            return users != null && users.Any();
          }
      }
  • Create the class CustomRoleService which inherits RoleService. Override IsRoleValid(string role).
    [ServiceConfiguration(typeof(RoleService))]
    public class CustomRoleService : RoleService
    {
      public CustomRoleService(IVirtualRoleRepository virtualRoleRepository) : base(virtualRoleRepository)
        {
        }
      /// <summary>
      /// Check whether a given role is still valid.
      /// </summary>
      public override bool IsRoleValid(string role)
        {
          var synUserRepo = ServiceLocator.Current.GetInstance<ISynchronizedUsersRepository>();
          var rolesStatus = synUserRepo.ListRoleStatus();
          var allRoles = (rolesStatus != null && rolesStatus.Any()) ? rolesStatus.Select(x => x.Name) : null;
          var isValid = (allRoles != null && allRoles.Any(roleName => string.Equals(roleName, role, System.StringComparison.OrdinalIgnoreCase))) ? true : false;
          return isValid || base.IsRoleValid(role);
        }
    }
  • Create the class CustomInitializationService which inherits InitializationService. Override GetAllRoles().
    [ServiceConfiguration(typeof(InitializationService))]
    public class CustomInitializationService : InitializationService
      {                
      /// <summary>
      /// Get all roles from system.
      /// </summary>
    protected override IEnumerable<string> GetAllRoles()
      {
        var synUserRepo = ServiceLocator.Current.GetInstance<ISynchronizedUsersRepository>();
        var rolesStatus = synUserRepo.ListRoleStatus();
        return (rolesStatus != null && rolesStatus.Any()) ? rolesStatus.Select(x => x.Name) : null;
      }        
    }
  •  Register three classes at the initialization module.
    [InitializableModule]
    public class DependencyResolverInitialization : IConfigurableModule
      {
        public void ConfigureContainer(ServiceConfigurationContext context)
          {
            //Implementations for custom interfaces can be registered here.
            context.ConfigurationComplete += (o, e) =>
              {
                //Register custom implementations that should be used in favour of the default implementations
                context.Services.AddTransient<IContentRenderer, ErrorHandlingContentRenderer>()
                .AddTransient<ContentAreaRenderer, AlloyContentAreaRenderer>()
                .AddTransient<UserService, CustomUserService>()
                .AddTransient<RoleService, CustomRoleService>()
                .AddTransient<InitializationService, CustomInitializationService>();
              };
          }
        public void Initialize(InitializationEngine context)
          {
            DependencyResolver.SetResolver(new ServiceLocatorDependencyResolver(context.Locate.Advanced));
          }
        public void Uninitialize(InitializationEngine context)
          {
          }
        public void Preload(string[] parameters)
          {
          }
      }

The code examples here give you the simplest code customizations. For more complicated scenarios, you can customize these classes accordingly.

Do you find this information helpful? Please log in to provide feedback.

Last updated: Jul 01, 2019

Recommendations [hide]