Mvc.ExceptionHandling.AbpExceptionFilter - No Component found

╄→гoц情女王★ 提交于 2020-06-17 13:16:49

问题


this is a follow-up question to the one posted here earlier today InvalidCastException on an LDAP implementation in ASP Boilerplate as suggested by just.another.programmer

I seem to be running into another issue this time having no component supported as described here in the logs

The code from before

LdapAuthentication.cs:

 public abstract class LdapAuthenticationSource<TTenant, TUser> : DefaultExternalAuthenticationSource<TTenant, TUser>, ITransientDependency
        where TTenant : AbpTenant<TUser>
        where TUser : AbpUserBase, new()
    {

        /// <summary>
        /// LDAP
        /// </summary>
        public const string SourceName = "LDAP";

        public override string Name
        {
            get { return SourceName; }
        }

        private readonly ILdapSettings _settings;
        private readonly IAbpZeroLdapModuleConfig _ldapModuleConfig;

        protected LdapAuthenticationSource(ILdapSettings settings, IAbpZeroLdapModuleConfig ldapModuleConfig)
        {
            _settings = settings;
            _ldapModuleConfig = ldapModuleConfig;
        }

        /// <inheritdoc/>
        public override async Task<bool> TryAuthenticateAsync(string userNameOrEmailAddress, string plainPassword, TTenant tenant)
        {
            if (!_ldapModuleConfig.IsEnabled || !(await _settings.GetIsEnabled(GetIdOrNull(tenant))))
            {
                return false;
            }

            using (var principalContext = await CreatePrincipalContext(tenant))
            {
                return ValidateCredentials(principalContext, userNameOrEmailAddress, plainPassword);
            }
        }

        /// <inheritdoc/>
        public async override Task<TUser> CreateUserAsync(string userNameOrEmailAddress, TTenant tenant)
        {
            await CheckIsEnabled(tenant);

            var user = await base.CreateUserAsync(userNameOrEmailAddress, tenant);

            using (var principalContext = await CreatePrincipalContext(tenant))
            {
                var userPrincipal = UserPrincipal.FindByIdentity(principalContext, userNameOrEmailAddress);

                if (userPrincipal == null)
                {
                    throw new AbpException("Unknown LDAP user: " + userNameOrEmailAddress);
                }

                UpdateUserFromPrincipal(user, userPrincipal);

                user.IsEmailConfirmed = true;
                user.IsActive = true;

                return user;
            }
        }

        public async override Task UpdateUserAsync(TUser user, TTenant tenant)
        {
            await CheckIsEnabled(tenant);

            await base.UpdateUserAsync(user, tenant);

            using (var principalContext = await CreatePrincipalContext(tenant))
            {
                var userPrincipal = UserPrincipal.FindByIdentity(principalContext, user.UserName);

                if (userPrincipal == null)
                {
                    throw new AbpException("Unknown LDAP user: " + user.UserName);
                }

                UpdateUserFromPrincipal(user, userPrincipal);
            }
        }

        protected virtual bool ValidateCredentials(PrincipalContext principalContext, string userNameOrEmailAddress, string plainPassword)
        {
            return principalContext.ValidateCredentials(userNameOrEmailAddress, plainPassword, ContextOptions.Negotiate);
        }

        protected virtual void UpdateUserFromPrincipal(TUser user, UserPrincipal userPrincipal)
        {
            user.UserName = userPrincipal.SamAccountName;
            user.Name = userPrincipal.GivenName;
            user.Surname = userPrincipal.Surname;
            user.EmailAddress = userPrincipal.EmailAddress;

            if (userPrincipal.Enabled.HasValue)
            {
                user.IsActive = userPrincipal.Enabled.Value;
            }
        }

        protected virtual async Task<PrincipalContext> CreatePrincipalContext(TTenant tenant)
        {
            var tenantId = GetIdOrNull(tenant);

            return new PrincipalContext(
                await _settings.GetContextType(tenantId),
                ConvertToNullIfEmpty(await _settings.GetDomain(tenantId)),
                ConvertToNullIfEmpty(await _settings.GetContainer(tenantId)),
                ConvertToNullIfEmpty(await _settings.GetUserName(tenantId)),
                ConvertToNullIfEmpty(await _settings.GetPassword(tenantId))
                );
        }

        private async Task CheckIsEnabled(TTenant tenant)
        {
            if (!_ldapModuleConfig.IsEnabled)
            {
                throw new AbpException("Ldap Authentication module is disabled globally!");
            }

            var tenantId = GetIdOrNull(tenant);
            if (!await _settings.GetIsEnabled(tenantId))
            {
                throw new AbpException("Ldap Authentication is disabled for given tenant (id:" + tenantId + ")! You can enable it by setting '" + LdapSettingNames.IsEnabled + "' to true");
            }
        }

        private static int? GetIdOrNull(TTenant tenant)
        {
            return tenant == null
                ? (int?)null
                : tenant.Id;
        }

        private static string ConvertToNullIfEmpty(string str)
        {
            return str.IsNullOrWhiteSpace()
                ? null
                : str;
        }

    }
}

LdapSettings.cs

public class LdapSettings: ILdapSettings, ITransientDependency
    {

        protected ISettingManager SettingManager { get; }

        public LdapSettings(ISettingManager settingManager)
        {
            SettingManager = settingManager;
        }

        public virtual Task<bool> GetIsEnabled(int? tenantId)
        {
            return tenantId.HasValue
                ? SettingManager.GetSettingValueForTenantAsync<bool>(AppSettingNames.IsEnabled, tenantId.Value)
                : SettingManager.GetSettingValueForApplicationAsync<bool>(AppSettingNames.IsEnabled);
        }

        public virtual async Task<ContextType> GetContextType(int? tenantId)
        {
            return tenantId.HasValue
                ? (await SettingManager.GetSettingValueForTenantAsync(AppSettingNames.ContextType, tenantId.Value)).ToEnum<ContextType>()
                : (await SettingManager.GetSettingValueForApplicationAsync(AppSettingNames.ContextType)).ToEnum<ContextType>();
        }

        public virtual Task<string> GetContainer(int? tenantId)
        {
            return tenantId.HasValue
                ? SettingManager.GetSettingValueForTenantAsync(AppSettingNames.Container, tenantId.Value)
                : SettingManager.GetSettingValueForApplicationAsync(AppSettingNames.Container);
        }

        public virtual Task<string> GetDomain(int? tenantId)
        {
            return tenantId.HasValue
                ? SettingManager.GetSettingValueForTenantAsync(AppSettingNames.Domain, tenantId.Value)
                : SettingManager.GetSettingValueForApplicationAsync(AppSettingNames.Domain);
        }

        public virtual Task<string> GetUserName(int? tenantId)
        {
            return tenantId.HasValue
                ? SettingManager.GetSettingValueForTenantAsync(AppSettingNames.UserName, tenantId.Value)
                : SettingManager.GetSettingValueForApplicationAsync(AppSettingNames.UserName);
        }

        public virtual Task<string> GetPassword(int? tenantId)
        {
            return tenantId.HasValue
                ? SettingManager.GetSettingValueForTenantAsync(AppSettingNames.Password, tenantId.Value)
                : SettingManager.GetSettingValueForApplicationAsync(AppSettingNames.Password);
        }
    }
}

CoreModule.cs

    [DependsOn(typeof(AbpZeroLdapModule))]
    public class TestApp2020CoreModule : AbpModule
    {
        public override void PreInitialize()
        {

            Configuration.Auditing.IsEnabledForAnonymousUsers = true;

            // Declare entity types
            Configuration.Modules.Zero().EntityTypes.Tenant = typeof(Tenant);
            Configuration.Modules.Zero().EntityTypes.Role = typeof(Role);
            Configuration.Modules.Zero().EntityTypes.User = typeof(User);

            TestApp2020LocalizationConfigurer.Configure(Configuration.Localization);

            // Enable this line to create a multi-tenant application.
            Configuration.MultiTenancy.IsEnabled = TestApp2020Consts.MultiTenancyEnabled;

            // IocManager.Register<ILdapSettings, MyLdapSettings>(); //change default setting source
            IocManager.Register<ILdapSettings, LdapSettings>();
            Configuration.Modules.ZeroLdap().Enable(typeof(LdapSettings));
            // Configure roles
            AppRoleConfig.Configure(Configuration.Modules.Zero().RoleManagement);

            Configuration.Settings.Providers.Add<AppSettingProvider>();
        }

        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(typeof(TestApp2020CoreModule).GetAssembly());
        }

        public override void PostInitialize()
        {
            IocManager.Resolve<AppTimes>().StartupTime = Clock.Now;
            SettingManager settingsManager = IocManager.Resolve<SettingManager>();
            settingsManager.ChangeSettingForApplication(AppSettingNames.IsEnabled, "true");
        }
    }
}

Once again, all help will be appreciated, thanks


回答1:


The problem is almost certainly with the constructor you used for LdapAuthenticationSource. There's two problems

  1. You declared the constructor protected. That means the IoC framework isn't able to create a new LdapAuthenticationSource.
  2. You didn't call the base constructor from your inherited class. Instead, you stored the params in fields of the derived class so the base class cannot access them!

Try changing the constructor like this

public LdapAuthenticationSource(ILdapSettings settings, IAbpZeroLdapModuleConfig ldapModuleConfig) : base(settings, ldapModuleConfig) { }

and removing these two lines

private readonly ILdapSettings _settings;
private readonly IAbpZeroLdapModuleConfig _ldapModuleConfig;


来源:https://stackoverflow.com/questions/62191897/mvc-exceptionhandling-abpexceptionfilter-no-component-found

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!