1

我想在多租户应用程序中进行身份验证后重定向 URL。

当用户在登录页面(URL:domain_name.com)上输入凭据并成功验证后,浏览器 URL 必须更改为{tenancy_name}.domain_name.com

我使用电子邮件地址和密码获得了租户名称。现在,我想将该租户名称放入浏览器 URL 中,以便为用户识别它。

这是用户忘记在 URL 中输入租户名称的情况,这意味着用户输入的 URL 如下:domain_name.com

然后在成功验证后,必须将租户名称添加到 URL 中,例如: {tenancy_name}.domain_name.com

并且必须重定向到仪表板页面。

以下是我的登录发布方法:

        [HttpPost]
        [UnitOfWork]
        public virtual async Task<ActionResult> Login(LoginViewModel loginModel, int paymentFlag, string returnUrl = "", string returnUrlHash = "")
        {
            try
            {
                var tenant = await _tenantManager.FindByTenancyNameAsync(loginModel.TenancyName);
                if (tenant.IsActive == true)
                {
                    if (tenant != null)
                    {
                        var payments = await _paymentRepository.GetAll().Where(p => p.TenantId == tenant.Id).FirstOrDefaultAsync();

                        if (paymentFlag == 0)
                        {
                            if (payments == null)
                            {
                                return RedirectToAction("Payment", loginModel);
                            }
                        }

                    }

                    var loginResult = await GetLoginResultAsync(loginModel.UsernameOrEmailAddress, loginModel.Password, loginModel.TenancyName);

                    var tenantId = loginResult.Tenant == null ? (int?)null : loginResult.Tenant.Id;

                    using (UnitOfWorkManager.Current.SetTenantId(tenantId))
                    {
                        if (loginResult.User.ShouldChangePasswordOnNextLogin)
                        {
                            loginResult.User.SetNewPasswordResetCode();

                            return RedirectToAction("ResetPassword", new
                            {
                                TenantId = SimpleStringCipher.Instance.Encrypt(tenantId == null ? null : tenantId.ToString()),
                                UserId = SimpleStringCipher.Instance.Encrypt(loginResult.User.Id.ToString()),
                                ResetCode = loginResult.User.PasswordResetCode
                            });
                        }

                        var signInResult = await _signInManager.SignInOrTwoFactorAsync(loginResult, loginModel.RememberMe);
                        if (signInResult == SignInStatus.RequiresVerification)
                        {


                            return RedirectToAction("SendSecurityCode", new
                            {
                                returnUrl = returnUrl + (returnUrlHash ?? ""),
                                rememberMe = loginModel.RememberMe
                            });
                        }

                        Debug.Assert(signInResult == SignInStatus.Success);

                        await UnitOfWorkManager.Current.SaveChangesAsync();

                        if (string.IsNullOrWhiteSpace(returnUrl))
                        {
                            returnUrl = GetAppHomeUrl();
                        }

                        if (!string.IsNullOrWhiteSpace(returnUrlHash))
                        {
                            returnUrl = returnUrl + returnUrlHash;
                        }


                    }
                }
                else
                {
                    throw new UserFriendlyException(L("UserEmailIsNotConfirmedAndCanNotLogin"));
                }
            }
            catch (UserFriendlyException ex)
            {
                return RedirectToAction("Login", new
                {
                    errorMessage = ex.Message
                });
            }
            return Json(new AjaxResponse { TargetUrl = returnUrl });                
        }
4

1 回答 1

0

I found a simple solution. Update app-initializer.ts as follows:

First, add method

private replaceTenantPlaceholder(baseUrl: string, defaultSubDomain: string): string {

    const tenancyNamePlaceHolder = '{TENANCY_NAME}';
    baseUrl = baseUrl.replace(tenancyNamePlaceHolder + '.', tenancyNamePlaceHolder);
    
    var subDomain = window.location.hostname.split(".")[0];
    subDomain = subDomain.replace(`$:{window.location.port}`, "");
    
    switch (window.location.hostname.split(".").length) {
        case 1:
        case 2:
            //No sub-domain on current url
            subDomain = defaultSubDomain;
            if (subDomain.length > 0) subDomain += ".";
            break;

        case 3:
            //Use the current url's sub-domain
            subDomain += ".";

        default:
    }
    
    return baseUrl.replace(tenancyNamePlaceHolder, subDomain);
}

Then update method getApplicationConfig:

AppConsts.appBaseUrl = this.replaceTenantPlaceholder(response.appBaseUrl, "www");
AppConsts.remoteServiceBaseUrl = this.replaceTenantPlaceholder(response.remoteServiceBaseUrl, "");

No other modifications needed for this part of the multi-tenancy. Make sure you update your Configuration.Modules.AbpWebCommon().MultiTenancy.DomainFormat in your CoreModule and define your CorsOrigins in appsettings.json

My client application requires "www" in the domain, so that is why I have the defaultSubDomain parameter. You can omit that if not needed.

于 2021-08-03T19:51:03.687 回答