Hello @aldercove,
Thanks for you reply.. There is no clear relationship between the candidates and customer/tenants. It's more of a separate entity. However, we figured it would be nice to use the authentication/authorization implementation of aspnetcore, because it will partly use the same API endpoints as the host and customer enviroment does.
The candidate users will be managed through the admin environment. So I think you can look at the candidate users as tenantless users (or each user is its own tenant).
@ismcagdas, I think we will go with this approach and perhaps split the users in a whole new database in the future. Thanks for the information about the custom filters! We will check them out.
Angular & .net core Version: V9.1.0 .NET core 3.1
So, I hope anyone can provide me with some proper insights on how to tackle this request/addition...
We are developing a large platform for a customer in which we need to create a seperation in user accounts.
Let's say we have 3 layers:
We either want to use the current AbpUsers table with a custom property of some sort.. but then we need to create filters in the appservices which are specific for the candidate users and the customer users. Is that a possiblity?
Option two is to create a separate user table, but I think we need to copy a lot of boilerplate code to get that to work.
Has anyone ever done this and has some pointers on how to approach this?
Thanks!
Hey, we've done this many times in our projects.
So we create a MyDomainTenantResolveContributor.cs in the root folder of the *.Web.Core project, with the following content:
public class MyDomainTenantResolveContributor : ITenantResolveContributor, ITransientDependency
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IWebMultiTenancyConfiguration _multiTenancyConfiguration;
private readonly ITenantStore _tenantStore;
private readonly ILocalizationManager _localizationManager;
public MyDomainTenantResolveContributor(
IHttpContextAccessor httpContextAccessor,
IWebMultiTenancyConfiguration multiTenancyConfiguration,
ITenantStore tenantStore,
ILocalizationManager localizationManager)
{
_httpContextAccessor = httpContextAccessor;
_multiTenancyConfiguration = multiTenancyConfiguration;
_tenantStore = tenantStore;
_localizationManager = localizationManager;
}
public int? ResolveTenantId()
{
if (_multiTenancyConfiguration.DomainFormat.IsNullOrEmpty())
{
return null;
}
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null)
{
return null;
}
var hostName = httpContext.Request.Host.Host.RemovePreFix("http://", "https://").RemovePostFix("/");
var domainFormat = _multiTenancyConfiguration.DomainFormat.RemovePreFix("http://", "https://").Split(':')[0].RemovePostFix("/");
var result = new FormattedStringValueExtracter().Extract(hostName, domainFormat, true, '/');
var tenancyName = result.Matches[0].Value;
if (string.Equals(tenancyName, "host", StringComparison.OrdinalIgnoreCase))
{
return null;
}
var tenantInfo = _tenantStore.Find(tenancyName);
if (tenantInfo == null)
{
var noTenantFound = _localizationManager.GetString(AppConsts.LocalizationSourceName, "NoTenantFound");
var noTenantFoundDetail = _localizationManager.GetString(AppConsts.LocalizationSourceName, "NoTenantFoundDetail");
throw new UserFriendlyException(noTenantFound, noTenantFoundDetail);
}
return tenantInfo.Id;
}
}
And then we add a reference to it in our PreInitialize method of the *WebMvcModule.cs:
if (!_env.IsDevelopment() && !_env.IsStaging()) { Configuration.MultiTenancy.Resolvers.Insert(0, typeof(MyDomainTenantResolveContributor)); }
We also added the same line in the PreInitialize method of the *WebCoreModule.cs, but not sure if that is needed though.