Mvc.ExceptionHandling.AbpExceptionFilter-找不到组件 [英] Mvc.ExceptionHandling.AbpExceptionFilter - No Component found
问题描述
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
之前的代码
LdapAuthentication.cs:
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
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
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
推荐答案
问题几乎可以肯定是与用于LdapAuthenticationSource
的构造函数有关的.有两个问题
The problem is almost certainly with the constructor you used for LdapAuthenticationSource
. There's two problems
- 您声明了构造函数
protected
.这意味着IoC框架无法创建新的LdapAuthenticationSource
. - 您没有从继承的类中调用
base
构造函数.相反,您将参数存储在派生类的字段中,因此基类无法访问它们!
- You declared the constructor
protected
. That means the IoC framework isn't able to create a newLdapAuthenticationSource
. - 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) { }
并删除这两行
private readonly ILdapSettings _settings;
private readonly IAbpZeroLdapModuleConfig _ldapModuleConfig;
这篇关于Mvc.ExceptionHandling.AbpExceptionFilter-找不到组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!