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

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

我正在尝试在未设置密码时强制重定向用户设置密码。

最初,用户将使用提供给用户的初始密码登录。 (

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" }
        );
    }
asp.net-mvc routes action-filter custom-action-filter
1个回答
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()))
© www.soinside.com 2019 - 2024. All rights reserved.