ASP.NET MVC全局过滤器提供重定向循环

时间:2018-10-30 02:28:00

标签: asp.net-mvc routes action-filter custom-action-filter

我试图在未设置密码时强制重定向用户设置密码。 最初,用户将使用提供给用户的初始密码登录。 (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);
    }
}

问题在于它提供了重定向循环。 Here's a screenshot from browser network tab

我还是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 :(得分:0)

我的坏。 这是另一个导致此重定向循环的问题

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()))