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

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.

Last updated: Oct 30, 2018

Feedback?