为什么我的自定义错误不断被重定向?

问题描述 投票:0回答:1

我正在向

AuthorizeAttribute
添加自定义代码,将用户路由到另一个控制器中的操作,该控制器在用户尚未验证其电话号码时显示模式弹出窗口。

由于某种原因,代码只是永远重定向,网站只是说:

重定向您太多次

并且没有达到我在

VerifyPhoneNumber
操作中设置的断点。

您能说明为什么会发生这种情况吗? 短暂性脑缺血发作。

这是我的自定义重写的

AuthorizeAttribute
类,远低于此。 这里的所有内容以前都在这里,我只是添加了:

  if (CustomContext.AccountDomainType == AccountDomainType.ActiveDirectory &&
                    CustomContext.IsPhoneNumberConfirmed == false)
                {
                    return false;
                }

并且:

if (CustomContext.AccountDomainType == AccountDomainType.ActiveDirectory &&
                    CustomContext.IsPhoneNumberConfirmed == false)
                {
                    filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
                    {
                        { "action", "VerifyPhoneNumber" },
                        { "controller", "Account" }
                    });

                    return;
                }

CustomAuthorizeAttribute
班级:

public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        public Module Module { get; set; }
        public Permission Permission { get; set; }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var CustomContext = (Context)httpContext.Items[Context.HttpContextItemName];
            var token = httpContext.Request.Form["token"];
            if (!base.AuthorizeCore(httpContext) && token == null)
            {
                return false;
            }
            else if (token != null)
            {
                var tokenRepository = new AuthenticationTokenRepository(CustomContext);
                var authenticationToken = tokenRepository.Get(token);
                if (authenticationToken == null)
                {
                    CustomContext.Log("Permission denied because authentication token was not valid");
                    return false;
                }
                var authenticationManager = httpContext.GetOwinContext().Authentication;
                var userManager = httpContext.GetOwinContext().Get<AspNetUserManager>();
                AspNetUser user;
                if (authenticationToken.Role == AuthenticationTokenRole.PdfGenerator)
                {
                    user = userManager.FindByName<AspNetUser, Guid>(authenticationToken.CreatedBy);
                    if (user == null)
                    {
                        CustomContext.Log("Permission denied because token creation user was not found");
                        return false;
                    }
                }
                else
                {
                    return false;
                }

                var userIdentity = ApplicationSignInManager.GenerateUserIdentity(userManager, user, DefaultAuthenticationTypes.ApplicationCookie);
                authenticationManager.SignIn(new AuthenticationProperties { IsPersistent = false }, userIdentity);
                if (!authenticationManager.User.Identity.IsAuthenticated)
                {
                    authenticationManager.User = authenticationManager.AuthenticationResponseGrant.Principal;
                }
            }
       
            if (token == null && !CustomContext.IsDeviceAuthorized())
            {
                CustomContext.UpdateDevice();
                httpContext.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.TwoFactorCookie, DefaultAuthenticationTypes.ApplicationCookie);
                CustomContext.Log("Permission denied and forced sign out because device was already signed out based on cookie check");
                return false;
            }
            if (Module != default(Module) && Permission != default(Permission) && !CustomContext.HasPermission(Module, Permission))
            {
                CustomContext.Log("Permission denied because user does not have permission to " + Module.DisplayName() + ", " + Permission.DisplayName());
                return false;
            }
            if (Module != default(Module) && Permission == default(Permission) && !CustomContext.HasModule(Module))
            {
                CustomContext.Log("Permission denied because company does not have the following module features turned on " + Module.DisplayName());
                return false;
            }
            if (CustomContext.IsPasswordExpired
                && httpContext.Request.RequestContext.RouteData.Values.ContainsKey("action")
                && "ChangePassword" != httpContext.Request.RequestContext.RouteData.Values["action"].ToString()
                && "ChangePasswordLink" != httpContext.Request.RequestContext.RouteData.Values["action"].ToString())
            {
                CustomContext.Log("Permission denied because password is expired. Password must be changed first");
                return false;
            }
            if (Module == default(Module) && Permission != default(Permission))
            {
                throw new Exception("No module specified for permission check");
            }
            
            if (CustomContext.AccountDomainType == AccountDomainType.ActiveDirectory &&
                CustomContext.IsPhoneNumberConfirmed == false)
            {
                return false;
            }
            
            return true;



        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                var actionParams = filterContext.ActionDescriptor.GetParameters();
                var paramTypes = actionParams.Select(ap => ap.ParameterType).ToArray();
                var actionMethod = filterContext.Controller.GetType()
                    .GetMethod(filterContext.ActionDescriptor.ActionName, paramTypes);
                var CustomContext = (Context)filterContext.HttpContext.Items[Context.HttpContextItemName];
                var errorTypeViewPrefix = CustomContext.IsPasswordExpired ? "PasswordExpired" : "PermissionDenied";

                if (CustomContext.AccountDomainType == AccountDomainType.ActiveDirectory &&
                    CustomContext.IsPhoneNumberConfirmed == false)
                {
                    filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
                    {
                        { "action", "VerifyPhoneNumber" },
                        { "controller", "Account" }
                    });

                    return;
                }
                if (actionMethod != null && (actionMethod.ReturnType == typeof(PartialViewResult) ||
                                             actionMethod.ReturnType == typeof(Task<PartialViewResult>)))
                    {
                        // Partial views
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
                        {
                            { "action", errorTypeViewPrefix + "Partial" },
                            { "controller", "Error" }
                        });

                        return;
                    }

                // Full page views
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
                {
                    { "action", errorTypeViewPrefix },
                    { "controller", "Error" }
                });
                return;
            
            }
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

我尝试执行的操作,向用户发送文本消息代码并打开弹出窗口(它存在于另一个控制器中):

 [Display(Name = "Verify Phone Number", Description = "Verify Phone Number")]
        public async Task<PartialViewResult> VerifyPhoneNumber()
        {
            var strictPhoneAttr = new StrictPhoneAttribute();
            if (!strictPhoneAttr.IsValid(Context.PhoneNumber))
            {
                ModelState.AddModelError(string.Empty, "Please, change your phone number to a valid cell phone number under the menu in the top right-hand corner under your name. A valid cell phone number is required for two-factor authentication used by this system.");
            }
            else
            {
           /....code that send SMS code ......./
            Context.Log("Opened Verify Phone Number modal");
            return PartialView("_VerifyPhoneNumber", new VerifyPhoneNumberModel());
        }
c# asp.net .net asp.net-mvc authorization
1个回答
0
投票
  1. 确保当用户重定向到

    VerifyPhoneNumber
    操作时,他们不会自动再次重定向到原始操作(由于正在评估相同的条件),我认为您可以添加一些日志记录来改进调试。

  2. 一旦成功验证电话号码,您可能需要更改逻辑以更新

    CustomContext.IsPhoneNumberConfirmed
    ,因为如果模式不允许用户解决问题,他们将继续被重定向。

  3. 您可以修改

    AuthorizeCore
    方法来检查当前操作是否为
    VerifyPhoneNumber
    。如果是这样,您可以跳过重定向:

if (filterContext.ActionDescriptor.ActionName == "VerifyPhoneNumber" && filterContext.ActionDescriptor.ControllerDescriptor.ControllerName == "Account")
{
    return true;
}
  1. 确保在
    HandleUnauthorizedRequest
    方法中,您没有创建导致相同重定向的多个条件。
  2. 这是
    AuthorizeCore
    方法的修改部分,可避免重定向循环:
if (CustomContext.AccountDomainType == AccountDomainType.ActiveDirectory &&
    CustomContext.IsPhoneNumberConfirmed == false)
{
    // check if we are already in the VerifyPhoneNumber action to prevent a redirect loop
    if (!(httpContext.Request.RequestContext.RouteData.Values["action"].ToString() == "VerifyPhoneNumber" &&
          httpContext.Request.RequestContext.RouteData.Values["controller"].ToString() == "Account"))
    {
        return false; // triggers redirect logic in HandleUnauthorizedRequest
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.