ASP.NET MVC Global Filter дает цикл перенаправления - PullRequest
0 голосов
/ 30 октября 2018

Я пытаюсь заставить пользователя перенаправить установить пароль, когда пароль не установлен. Первоначально пользователь будет входить в систему с использованием начального пароля, предоставленного пользователю. (Значение PasswordHash равно нулю. Я использую другое значение initialPassword).

Поэтому, когда PasswordHash по-прежнему равен нулю, пользователь перенаправляется на страницу SetPassword.

Глобальный фильтр, который я сделал, это

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new CheckCandidatePasswordSetFilterAttribute());
    }
}



public class CheckCandidatePasswordSetFilterAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var principal = (ClaimsPrincipal)filterContext.HttpContext.User;

        if (principal.Identity.IsAuthenticated && principal.IsInRole(RoleNames.CandidateRole) &&
            !IsRouteSetToSetPassword(filterContext.RouteData.Values) && !IsRouteIsLogout(filterContext.RouteData.Values))
        {
            bool hasPassword = principal.HasClaim(CustomClaimTypes.CandidateHasPassword, true.ToString());
            if (!hasPassword)
            {
                filterContext.Result = new RedirectToRouteResult(new System.Web.Routing.RouteValueDictionary(new
                {
                    area = string.Empty,
                    controller = "Manage",
                    action = "SetPassword"
                }));
            }
            return;
        }

        base.OnActionExecuting(filterContext);
    }

    private bool IsRouteIsLogout(RouteValueDictionary routeData)
    {
        routeData.TryGetValue("area", out object area);
        if (area != null && !area.ToString().Equals(string.Empty))
            return false;

        if (!routeData.TryGetValue("controller", out object controller))
            return false;
        if (!routeData.TryGetValue("action", out object action))
            return false;

        return controller.ToString().Equals("Account", StringComparison.OrdinalIgnoreCase) && action.ToString().Equals("LogOff", StringComparison.OrdinalIgnoreCase);
    }

    private static bool IsRouteSetToSetPassword(RouteValueDictionary routeData)
    {
        routeData.TryGetValue("area", out object area);
        if (area != null && !area.ToString().Equals(string.Empty))
            return false;

        if (!routeData.TryGetValue("controller", out object controller))
            return false;
        if (!routeData.TryGetValue("action", out object action))
            return false;

        return controller.ToString().Equals("Manage", StringComparison.OrdinalIgnoreCase) && action.ToString().Equals("SetPassword", StringComparison.OrdinalIgnoreCase);
    }
}

Проблема в том, что он дает цикл перенаправления. Вот скриншот с вкладки сети браузера

Я все еще новичок в MVC и все еще озадачен этим.

Конфигурация маршрута:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new string[] { "ERecruitment.Controllers" }
        );
    }

1 Ответ

0 голосов
/ 30 октября 2018

Мой плохой. Это проблема в другом месте, которая вызывает этот цикл перенаправления

public ActionResult SetPassword()
    {
        var principal = (ClaimsPrincipal)User;
        if(principal.IsInRole(RoleNames.CandidateRole) 
              //the code below is the problem
             && principal.FindFirst(CustomClaimTypes.CandidateHasPassword).Equals(false.ToString()))
            return View();

        return RedirectToAction("Index", "Home");
    }

Мне просто нужно изменить код на

if(principal.IsInRole(RoleNames.CandidateRole) && principal.HasClaim(CustomClaimTypes.CandidateHasPassword, false.ToString()))
...