Как отладить ошибку проверки состояния представления в DNN? - PullRequest
0 голосов
/ 03 мая 2018

У меня есть приложение DotNetNuke, которое я унаследовал, и я пытаюсь внести некоторые изменения в существующий модуль. Это пользовательский модуль входа в систему.

Я пытаюсь интегрировать двухфакторную аутентификацию. Сам логин работает, но когда я затем хочу отобразить 2 факторных поля, я получаю ошибку 503 при представлении 2-х факторного кода.

Я пытался добавить событие Application_Error в global.asax, но это никогда не удавалось. Я также пытался переопределить событие OnError элемента управления входом, но оно также никогда не срабатывало.

OnInit всегда срабатывает во время обратной передачи, которая производит 503, но не OnLoad. Самым странным является то, что если я перейду через каждую строку OnInit, пока не нажму первую вещь за пределами OnInit, а затем нажму «Продолжить», все работает нормально. Если я просто нажму «Продолжить» с точки останова в начале OnInit, произойдет сбой с 503 до достижения OnLoad, почти каждый раз.

Это указывает на какую-то асинхронную ошибку, но я не могу представить, что это может быть.

Поля входа против 2-х факторов отображаются и скрываются элементами управления Panel, если это имеет какое-либо значение.

Сообщение об ошибке 503: «В настоящее время для этой установки не существует сайтов».

Любые предложения о том, как сузить причины 503, очень приветствуются.

Обновление

Я пропустил запись в журнале для исключения проверки состояния представления.

Validation of viewstate MAC failed. If this application is hosted by a Web
Farm or cluster, ensure that configuration specifies the same validationKey 
and validation algorithm. AutoGenerate cannot be used in a cluster. 
See http://go.microsoft.com/fwlink/?LinkID=314055 for more information.

Я установил значения ключей машины, но все равно получаю ту же ошибку. Не говоря уже о том, что это также не объясняет, почему это происходит, только если я не перешагнул OnInit

Есть мысли?

1 Ответ

0 голосов
/ 04 мая 2018

Оказывается, моя проблема возникла из-за вызова UserController.UserLogin() до попытки проверки двухфакторной аутентификации.

Теперь, когда я звоню, после двухфакторной проверки все работает, как ожидалось, и даже последовательно: o)

Код

Вот пример того, что изменилось.

Вот что не сработало:

private void ValidateUser(UserInfo objUser, bool ignoreExpiring)
{
    UserValidStatus validStatus = UserValidStatus.VALID;
    string strMessage = Null.NullString;
    DateTime expiryDate = Null.NullDate;
    bool okToShowPanel = true;

    validStatus = UserController.ValidateUser(objUser, PortalId, ignoreExpiring);

    if (PasswordConfig.PasswordExpiry > 0)
    {
        expiryDate = objUser.Membership.LastPasswordChangeDate.AddDays(PasswordConfig.PasswordExpiry);
    }
    UserId = objUser.UserID;

    //Check if the User has valid Password/Profile
    switch (validStatus)
    {
        case UserValidStatus.VALID:
            //check if the user is an admin/host and validate their IP
            if (Host.EnableIPChecking)
            {
                bool isAdminUser = objUser.IsSuperUser || PortalSettings.UserInfo.IsInRole(PortalSettings.AdministratorRoleName); ;
                if (isAdminUser)
                {
                    if (IPFilterController.Instance.IsIPBanned(Request.UserHostAddress))
                    {
                        new PortalSecurity().SignOut();
                        AddModuleMessage("IPAddressBanned", ModuleMessage.ModuleMessageType.RedError, true);
                        okToShowPanel = false;
                        break;
                    }
                }
            }

            //Set the Page Culture(Language) based on the Users Preferred Locale
            if ((objUser.Profile != null) && (objUser.Profile.PreferredLocale != null))
            {
                Localization.SetLanguage(objUser.Profile.PreferredLocale);
            }
            else
            {
                Localization.SetLanguage(PortalSettings.DefaultLanguage);
            }

            //Set the Authentication Type used 
            AuthenticationController.SetAuthenticationType(AuthenticationType);

            var userRequestIPAddress = new UserRequestIPAddressController();
            //Complete Login
            UserController.UserLogin(PortalId, objUser, PortalSettings.PortalName, userRequestIPAddress.GetUserRequestIPAddress(new HttpRequestWrapper(Request)), RememberMe);

            var twoFactorAuthStatus = GetTwoFactorAuthStatus(objUser);

            switch (twoFactorAuthStatus)
            {
                case TwoFactorAuthStatus.Error:
                    return;
                case TwoFactorAuthStatus.NotEnabled:
                    RedirectUser(objUser);
                    break;
                case TwoFactorAuthStatus.SetupNeeded:
                    PageNo = googleAuthSetupPageNo;
                    break;
                case TwoFactorAuthStatus.VerificationNeeded:
                    PageNo = verifyGoogleAuthPageNo;
                    break;
            }
            break;
        case UserValidStatus.PASSWORDEXPIRED:
            strMessage = string.Format(Localization.GetString("PasswordExpired", LocalResourceFile), expiryDate.ToLongDateString());
            AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
            PageNo = passwordPageNo;
            pnlProceed.Visible = false;
            break;
        case UserValidStatus.PASSWORDEXPIRING:
            strMessage = string.Format(Localization.GetString("PasswordExpiring", LocalResourceFile), expiryDate.ToLongDateString());
            AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
            PageNo = passwordPageNo;
            pnlProceed.Visible = true;
            break;
        case UserValidStatus.UPDATEPASSWORD:
            AddModuleMessage("PasswordUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
            PageNo = passwordPageNo;
            pnlProceed.Visible = false;
            break;
        case UserValidStatus.UPDATEPROFILE:
            //Save UserID in ViewState so that can update profile later.
            UserId = objUser.UserID;

            //When the user need update its profile to complete login, we need clear the login status because if the login is from
            //3rd party login provider, it may call UserController.UserLogin because they doesn't check this situation.
            new PortalSecurity().SignOut();
            //Admin has forced profile update
            AddModuleMessage("ProfileUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
            PageNo = profilePageNo;
            break;
    }
    if (okToShowPanel) ShowPanel();
}

Вот что сработало:

private void ValidateUser(UserInfo objUser, bool ignoreExpiring)
{
    UserValidStatus validStatus = UserValidStatus.VALID;
    string strMessage = Null.NullString;
    DateTime expiryDate = Null.NullDate;
    bool okToShowPanel = true;

    validStatus = UserController.ValidateUser(objUser, PortalId, ignoreExpiring);

    if (PasswordConfig.PasswordExpiry > 0)
    {
        expiryDate = objUser.Membership.LastPasswordChangeDate.AddDays(PasswordConfig.PasswordExpiry);
    }
    UserId = objUser.UserID;

    //Check if the User has valid Password/Profile
    switch (validStatus)
    {
        case UserValidStatus.VALID:
            //check if the user is an admin/host and validate their IP
            if (Host.EnableIPChecking)
            {
                bool isAdminUser = objUser.IsSuperUser || PortalSettings.UserInfo.IsInRole(PortalSettings.AdministratorRoleName); ;
                if (isAdminUser)
                {
                    if (IPFilterController.Instance.IsIPBanned(Request.UserHostAddress))
                    {
                        new PortalSecurity().SignOut();
                        AddModuleMessage("IPAddressBanned", ModuleMessage.ModuleMessageType.RedError, true);
                        okToShowPanel = false;
                        break;
                    }
                }
            }

            var twoFactorAuthStatus = GetTwoFactorAuthStatus(objUser);

            switch (twoFactorAuthStatus)
            {
                case TwoFactorAuthStatus.Error:
                    return;
                case TwoFactorAuthStatus.NotEnabled:
                    LoginUser(objUser);
                    break;
                case TwoFactorAuthStatus.SetupNeeded:
                    PageNo = googleAuthSetupPageNo;
                    break;
                case TwoFactorAuthStatus.VerificationNeeded:
                    PageNo = verifyGoogleAuthPageNo;
                    break;
            }
            break;
        case UserValidStatus.PASSWORDEXPIRED:
            strMessage = string.Format(Localization.GetString("PasswordExpired", LocalResourceFile), expiryDate.ToLongDateString());
            AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
            PageNo = passwordPageNo;
            pnlProceed.Visible = false;
            break;
        case UserValidStatus.PASSWORDEXPIRING:
            strMessage = string.Format(Localization.GetString("PasswordExpiring", LocalResourceFile), expiryDate.ToLongDateString());
            AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
            PageNo = passwordPageNo;
            pnlProceed.Visible = true;
            break;
        case UserValidStatus.UPDATEPASSWORD:
            AddModuleMessage("PasswordUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
            PageNo = passwordPageNo;
            pnlProceed.Visible = false;
            break;
        case UserValidStatus.UPDATEPROFILE:
            //Save UserID in ViewState so that can update profile later.
            UserId = objUser.UserID;

            //When the user need update its profile to complete login, we need clear the login status because if the login is from
            //3rd party login provider, it may call UserController.UserLogin because they doesn't check this situation.
            new PortalSecurity().SignOut();
            //Admin has forced profile update
            AddModuleMessage("ProfileUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
            PageNo = profilePageNo;
            break;
    }
    if (okToShowPanel) ShowPanel();
}

Я изменил RedirectUser() из первого примера на LoginUser(), который также выполняет перенаправление. LoginUser() также вызывается после успешной двухфакторной аутентификации и / или настройки.

Это более безопасный способ справиться с этим в целом. Обратная связь по отладке, которую я получал, была просто super , что вводило в заблуждение.

...