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

Content Delivery API and Azure AD

This topic gives you an 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 GetAllRoles() and IsRoleValid(string role).
    /// <summary>
    /// Responsible for manipulating with role
    /// </summary>
    [ServiceConfiguration(typeof(RoleService))]
    public class CustomRoleService: RoleService
      {
        public CustomRoleService(IVirtualRoleRepository virtualRoleRepository) : base(virtualRoleRepository)
          {
          }
        /// <summary>
        /// Get all roles from system.
        /// </summary>
        public 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;
          }
        /// <summary>
        /// Check whether a given role is still valid.
        /// </summary>
        public override bool IsRoleValid(string role)
          {
            var allRoles = GetAllRoles();
            var isValid =  (allRoles != null && allRoles.Any(roleName => string.Equals(roleName, role, System.StringComparison.OrdinalIgnoreCase))) ? true : false;
            return isValid || base.IsRoleValid(role);
          }
      }
  •  Register two classes at 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>();
              };
          }
        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 two classes accordingly.

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

Last updated: Jul 01, 2019