Hi,
I'm trying to use the subdomain as Tenant approach. I updated my appconfig to use the https://{TENANCY_NAME}.clientname.com/. This works fine, how ever.. my host tenant (so the login without a tenant name) is not clientname.com but instead it is admin.clientname.com.
This causes some errors though. If I navigate to admin.clientname.com and log in. I am actually in the host environment. When I then login as a tenant through the Tenant menu, it all works fine. How ever, when I try to switch back to the host, I recieve the following error: "Current tenant is different than given tenant. AbpSession.TenantId: 19, given TenantId: ".
The above is probably because it expects the host domain to be clientname.com, but instead it is host.clientname.com.
Is there any way to set the host subdomain somewhere, or fix this some other way?
EDIT: Using version v5.2.6 ASPNET CORE MVC & JQUERY .NET Framework
Thanks in advance!
14 Answer(s)
-
0
Fixed in v5.6
-
0
<cite>aaron: </cite> Fixed in v5.6
Hmmm, still doesn't work... getting the following error when switching back to host:
System.Exception: Current tenant is different than given tenant. AbpSession.TenantId: 18, given tenantId: at Robin.Authorization.Impersonation.ImpersonationManager.CheckCurrentTenant(Nullable`1 tenantId) at Robin.Authorization.Impersonation.ImpersonationManager.<GetImpersonatedUserAndIdentity>d__8.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Robin.Web.Controllers.AccountController.<ImpersonateSignIn>d__51.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__5`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at lambda_method(Closure , Object ) at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult() at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfActionResultExecutor.<Execute>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runti...
-
0
Hi @michelmk2,
You need to implement your own DomainTenantResolveContributor and return null if found tenancy name is admin. See <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.AspNetCore/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs">https://github.com/aspnetboilerplate/as ... ributor.cs</a>
-
0
<cite>ismcagdas: </cite> Hi @michelmk2,
You need to implement your own DomainTenantResolveContributor and return null if found tenancy name is admin. See <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.AspNetCore/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs">https://github.com/aspnetboilerplate/as ... ributor.cs</a>
Thanks for your reply! Do you have an example on how to implement this? Because i'm not sure how and where to put it!
Thank you so much!
-
0
It should be something like this;
public class MyDomainTenantResolveContributor : ITenantResolveContributor, ITransientDependency { 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, '/'); if (!result.IsMatch || !result.Matches.Any()) { return null; } var tenancyName = result.Matches[0].Value; if (tenancyName.IsNullOrEmpty()) { return null; } if(tenancyName == "admin"){ // this is the added line return null; } if (string.Equals(tenancyName, "www", StringComparison.OrdinalIgnoreCase)) { return null; } var tenantInfo = _tenantStore.Find(tenancyName); if (tenantInfo == null) { return null; } return tenantInfo.Id; } }
Then, add it to resolvers in the PreInitalize method of your web module
Configuration.MultiTenancy.Resolvers.Insert(0,new MyDomainTenantResolveContributor());
-
0
<cite>ismcagdas: </cite> It should be something like this;
public class MyDomainTenantResolveContributor : ITenantResolveContributor, ITransientDependency { 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, '/'); if (!result.IsMatch || !result.Matches.Any()) { return null; } var tenancyName = result.Matches[0].Value; if (tenancyName.IsNullOrEmpty()) { return null; } if(tenancyName == "admin"){ // this is the added line return null; } if (string.Equals(tenancyName, "www", StringComparison.OrdinalIgnoreCase)) { return null; } var tenantInfo = _tenantStore.Find(tenancyName); if (tenantInfo == null) { return null; } return tenantInfo.Id; } }
Then, add it to resolvers in the PreInitalize method of your web module
Configuration.MultiTenancy.Resolvers.Insert(0,new MyDomainTenantResolveContributor());
Still doesn't work unfortunately. Getting the following error:
System.ArgumentNullException: Value cannot be null. Parameter name: value at System.Security.Claims.Claim..ctor(String type, String value, String valueType, String issuer, String originalIssuer, ClaimsIdentity subject, String propertyKey, String propertyValue) at System.Security.Claims.Claim..ctor(String type, String value) at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory`1.<GenerateClaimsAsync>d__10.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory`2.<GenerateClaimsAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory`1.<CreateAsync>d__9.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Authorization.AbpUserClaimsPrincipalFactory`2.<CreateAsync>d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithPostActionAndFinallyAndGetResult>d__5`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwa...
-
0
@michelmk2 does it work like it used to be when you comment out the line below ?
Configuration.MultiTenancy.Resolvers.Insert(0,new MyDomainTenantResolveContributor());
-
0
<cite>ismcagdas: </cite> @michelmk2 does it work like it used to be when you comment out the line below ?
Configuration.MultiTenancy.Resolvers.Insert(0,new MyDomainTenantResolveContributor());
That gives me the same error as above :(.
-
0
@michelmk2 sorry for our late response. This is strange. If you comment out the code I have suggested, it should take you back to old case.
Did you make additional changes on the project regarding to this problem ?
-
0
<cite>ismcagdas: </cite> @michelmk2 sorry for our late response. This is strange. If you comment out the code I have suggested, it should take you back to old case.
Did you make additional changes on the project regarding to this problem ?
Unfortunately I'm still having the same problem. Tried all kinds of things.
I just discovered that the error I'm getting is because in the UserLinkManager.cs, method GetSwitchedUserAndIdentity, the _userManager is null, therefore it crashes and I get the error the the value cannot be null. The _userManager in the UserLinkManager class is not empty when I switch between tenants (subdomainds) it ONLY happens when I switch back to the host. :(.
Any idea why it's empty when switch back to the host? Thanks!!
-
0
@michelmk2 this is strange. UserLinkManager class is craeted via dependency injection, so UserManager on it also created via DI.
I couldn't understand why UserManager is null when switching back to host.
If this is a repeatable problem on your project, could you share your project via email ?
-
0
<cite>ismcagdas: </cite> @michelmk2 this is strange. UserLinkManager class is craeted via dependency injection, so UserManager on it also created via DI.
I couldn't understand why UserManager is null when switching back to host.
If this is a repeatable problem on your project, could you share your project via email ?
Thanks, I will somewhere next week!
-
0
I still have this issue. I just sent you a sample project again in which you can see what goes wrong. The email is from [email protected].
Thanks,
Bart
-
0
Fixed by applying https://github.com/aspnetzero/aspnet-zero-core/issues/1609!