Base solution for your next web application
Open Closed

Tenant login Issue #4018


User avatar
0
XugoWebTeam created

Hi Team,

I have spent a couple days on the tenant login via subdomian but still cannot make it work properly. My project is Asp.net Core and Angular. It was downloaded in early August which is still the latest version I think.

The client side and host side are both deployed on the server. Below is my appsetting.json: Client Side: "remoteServiceBaseUrl": "http://{TENANCY_NAME}.host.xugo.com.au", "appBaseUrl": "http://{TENANCY_NAME}.portal.xugo.com.au",

Host Side: "ServerRootAddress": "http://{TENANCY_NAME}.host.xugo.com.au", "ClientRootAddress": "http://{TENANCY_NAME}.portal.xugo.com.au", "CorsOrigins": "http://demo.portal.xugo.com.au/,http://portal.xugo.com.au/"

Can you please confirm if the setting are correct? I kept getting the <a class="postlink" href="http://demo.host.xugo.com.au/AbpUserConfiguration/GetAll">http://demo.host.xugo.com.au/AbpUserCon ... ion/GetAll</a> 500 internal error.

If I change the host side setting into "ServerRootAddress": "http://host.xugo.com.au", I won't get error. But login via tenant subdomain does not work. It only accepts the host login.

Thanks a lot!


13 Answer(s)
  • User Avatar
    0
    aaron created
    Support Team

    Can you check the error log?

  • User Avatar
    0
    XugoWebTeam created

    looks like a CORS issue?

    DEBUG 2017-10-10 02:49:47,611 [libuv] Microsoft.AspNetCore.Server.Kestrel - Connection id "0HL8FGP2144VS" started. INFO 2017-10-10 02:49:47,611 [11 ] soft.AspNetCore.Hosting.Internal.WebHost - Request starting HTTP/1.1 GET <a class="postlink" href="http://demo.host.xugo.com.au/AbpUserConfiguration/GetAll">http://demo.host.xugo.com.au/AbpUserCon ... ion/GetAll</a> application/json DEBUG 2017-10-10 02:49:47,611 [11 ] IdentityServer4.CorsPolicyProvider - CORS request made for path: /AbpUserConfiguration/GetAll from origin: <a class="postlink" href="http://demo.portal.xugo.com.au">http://demo.portal.xugo.com.au</a> but rejected because invalid CORS path DEBUG 2017-10-10 02:49:47,611 [11 ] n.Cookies.CookieAuthenticationMiddleware - AuthenticationScheme: Identity.Application was not authenticated. DEBUG 2017-10-10 02:49:47,611 [11 ] IdentityServer4.Hosting.EndpointRouter - No endpoint entry found for request path: /AbpUserConfiguration/GetAll INFO 2017-10-10 02:49:47,611 [11 ] entication.JwtBearer.JwtBearerMiddleware - Successfully validated the token. INFO 2017-10-10 02:49:47,611 [11 ] entication.JwtBearer.JwtBearerMiddleware - HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Bearer. ERROR 2017-10-10 02:49:47,627 [11 ] entication.JwtBearer.JwtBearerMiddleware - Exception occurred while processing message. System.InvalidOperationException: IDX10803: Unable to obtain configuration from: 'http://{TENANCY_NAME}.host.xugo.com.au/.well-known/openid-configuration'. ---> System.IO.IOException: IDX10804: Unable to retrieve document from: 'http://{TENANCY_NAME}.host.xugo.com.au/.well-known/openid-configuration'. ---> System.UriFormatException: Invalid URI: The hostname could not be parsed. at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind) at System.Uri..ctor(String uriString, UriKind uriKind) at System.Net.Http.HttpClient.CreateUri(String uri) at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.<GetDocumentAsync>d__8.MoveNext() --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.<GetDocumentAsync>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 Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.<GetAsync>d__3.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 System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.IdentityModel.Protocols.ConfigurationManager1.<GetConfigurationAsync>d__24.MoveNext() --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.ConfigurationManager1.<GetConfigurationAsync>d__24.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 System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__1.MoveNext() ERROR 2017-10-10 02:49:47,627 [11 ] Microsoft.AspNetCore.Server.Kestrel - Connection id "0HL8FGP2144VS": An unhandled exception was thrown by the application. System.InvalidOperationException: IDX10803: Unable to obtain configuration from: 'http://{TENANCY_NAME}.host.xugo.com.au/.well-known/openid-configuration'. ---> System.IO.IOException: IDX10804: Unable to retrieve document from: 'http://{TENANCY_NAME}.host.xugo.com.au/.well-known/openid-configuration'. ---> System.UriFormatException: Invalid URI: The hostname could not be parsed. at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind) at System.Uri..ctor(String uriString, UriKind uriKind) at System.Net.Http.HttpClient.CreateUri(String uri) at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.<GetDocumentAsync>d__8.MoveNext() --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.<GetDocumentAsync>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 Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.<GetAsync>d__3.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 System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.IdentityModel.Protocols.ConfigurationManager1.<GetConfigurationAsync>d__24.MoveNext() --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.ConfigurationManager1.<GetConfigurationAsync>d__24.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 System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>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 Microsoft.AspNetCore.Authentication.AuthenticationHandler1.<InitializeAsync>d__52.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.Authentication.AuthenticationMiddleware1.<Invoke>d__18.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 IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationMiddleware.<Invoke>d__7.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.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.<Invoke>d__18.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 IdentityServer4.Hosting.IdentityServerMiddleware.<Invoke>d__3.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 IdentityServer4.Hosting.FederatedSignOutMiddleware.<Invoke>d__6.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 IdentityServer4.Hosting.AuthenticationMiddleware.<Invoke>d__2.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.Cors.Infrastructure.CorsMiddleware.<Invoke>d__7.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 IdentityServer4.Hosting.BaseUrlMiddleware.<Invoke>d__2.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.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.<Invoke>d__18.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.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.<Invoke>d__18.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.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.<Invoke>d__18.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.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.<Invoke>d__18.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.Cors.Infrastructure.CorsMiddleware.<Invoke>d__7.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.Server.IISIntegration.IISMiddleware.<Invoke>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 Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.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 System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame`1.

  • User Avatar
    0
    XugoWebTeam created

    The client side and host side are all in Azure. The CORS is set "*" on Azure. Otherwise it will get CORS error.

  • User Avatar
    0
    piapps created

    If * as the CORS setting works, it means you current CORS config is probably slightly wrong

    Can you try a few other combinations in the CORS origin to see if you can find the offending one?

    For example in your log it is failing on <a class="postlink" href="http://demo.host.xugo.com.au/">http://demo.host.xugo.com.au/</a>

    So you will need a CORS entry for that, as far as i am aware, TENANCY NAME works by replacing that var for the server address in the .json. So if its set to {TENANCY_NAME}.host.xugo.com.au and you visit demo.portal.xugo.com.au then angular will be asking for demo.host.xugo.com.au

    If that makes sense?

  • User Avatar
    0
    aaron created
    Support Team
  • User Avatar
    0
    XugoWebTeam created

    I have tried all kinds of CORS setting, still have no luck. Do I set the ServerRootAddress or ClientRootAddress incorrectly?

  • User Avatar
    0
    XugoWebTeam created

    Solved Now!

    1. The host side does NOT need any {tenancy_name} in the ServerRootAddress or ClientRootAddress.

    2. Not sure about other templates, but in the .Net core & Angular - NetFrameWork-4.6 , the multi-tenancy does not check the sub-domain if there no tenant data in the session. Sounds like a bug in the template.

    3. My solution is adding my own codes to do the sub-domain checking in the login screen if no tenant data in the session and multi-tenancy is enabled.

    Now it works, finally!

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @XugoWebTeam,

    I'm glad that you have fixed your problem. Our demo is ASP.NET Core & angular 2 and it works with subdomain. But, I couldn't figure out what was your main problem.

  • User Avatar
    0
    XugoWebTeam created

    Hi @ismcagdas,

    The issue was if I clear all the cache and start with a clean environment. Login Demo.xugo.com.au requires the host user id and password and login as host rather then the tenant Demo.

    If I login as Demo from the User page in host admin, then Demo.xugo.com.au requires the Demo user id and password.

    Basically, it does not check the Tenant name from URL if no cookie of the tenant is found.

  • User Avatar
    0
    rafalpiotrowski created

    Angular UI appconfig.json should contain "appBaseUrl": "http://{TENANCY_NAME}.yourdomain.com",

    everything elese without {TENANCY_NAME}

    also add bindings to the angualr UI web app in IIS

  • User Avatar
    0
    ismcagdas created
    Support Team

    Thanks @rafalpiotrowski :),

    @XugoWebTeam, if you cannot make it work, can you share your configurations about website address with us ? If you are using ASP.NET Core & Angular version please share both *.Host and angular app configs.

    Also, which version of ABP currently you are using ?

  • User Avatar
    0
    vladsd created

    What is ClientRootAddress on host should be when multi tenant is on with subdomains?

    Code below suggests that ClientRootAddress should have TENANCY_NAME as well

    See WebUrlServiceBase

    public string WebSiteRootAddressFormat => _appConfiguration[WebSiteRootAddressFormatKey] ?? "http://localhost:62114/";
    
            public string ServerRootAddressFormat => _appConfiguration[ServerRootAddressFormatKey] ?? "http://localhost:62114/";
    
            public bool SupportsTenancyNameInUrl
            {
                get
                {
                    var siteRootFormat = WebSiteRootAddressFormat;
                    return !siteRootFormat.IsNullOrEmpty() && siteRootFormat.Contains(TenancyNamePlaceHolder);
                }
            }
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Yes, if you are using tenancy name for angular client side url, then ClientRootAddress on the server side must contain {TENANCY_NAME} placeholder.