asp.net-mvc - 路由约束破坏了授权属性过滤器 - MVC 4

标签 asp.net-mvc asp.net-mvc-4 forms-authentication asp.net-mvc-routing

添加路由约束后,我注意到当导航到应用此路由约束的 URL 时,我的应用程序不再执行我的授权属性过滤器。

FilterConfig.cs

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new AuthorizeAttribute());
}

ProjectsController.cs
public class ProjectsController : Controller
{
    private IRepository<Project> repository;

    public ProjectsController()
    {
        repository = new Repository<Project>();
    }

    public ActionResult Edit(int id)
    {
        Project project = repository.FindById(id);

        if (project == null)
            return HttpNotFound();

        ProjectsEditViewModel projectVM = new ProjectsEditViewModel(project);

        return View("Edit", projectVM);
    }
}

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

        routes.MapRoute(
            name: "ProjectEdit",
            url: "Projects/Edit/{id}",
            defaults: new { controller = "Projects", action = "Edit" },
            constraints: new { id = new IsValidProjectConstraint() }
        );
    }
}

IsValidProjectConstraint.cs
public class IsValidProjectConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        IRepository<Project> projectsRepository = new Repository<Project>();

        try
        {
            int iProjectId;
            Project project;

            // Check for valid id
            if (int.TryParse(values["id"].ToString(), out iProjectId))
            {
                project = projectsRepository.FindById(iProjectId);

                // Check if this project exists
                if (project == null)
                {
                    return false;
                }
            }
            else
            {
                return false;
            }

            // If we made it here everything is good
            return true;
        }
        catch (Exception ex)
        {
            Log.WriteLine(ex.ToString());
            return false;
        }
    }
}

Web.Config
<authentication mode="Forms">
  <forms loginUrl="~/SAML/saml2" timeout="2880" />
</authentication>

添加此路由约束后,导航到 http://myurl/Projects/Edit/1在新的浏览器中实际上会呈现页面,就好像我已经通过身份验证一样。但是,当删除路由约束然后导航到 http://myurl/Projects/Edit/1 时我按预期重定向到我的登录操作。

似乎任何路由约束,无论是我的自定义路由约束还是只是一个正则表达式,都会导致这个问题。

有什么我在这里想念的吗?

编辑:
我想我应该提到我如何发布我的 FormsAuthentication cookie。我的应用程序充当 SAML 服务提供者,其中来自身份提供者的 SAML 响应被发送到我的断言使用者服务。 acs 解析 SAML 响应并对其进行验证,然后通过以下代码发出身份验证票证:
private void IssueAuthTicket(User userData)
{
    FormsAuthenticationTicket ticket =
        new FormsAuthenticationTicket(1, userData.UserName,
            DateTime.Now, DateTime.Now.AddMinutes(30),
            rememberMe, userData.Id.ToString());

    string ticketString = FormsAuthentication.Encrypt(ticket);

    HttpCookie cookie =
        new HttpCookie(FormsAuthentication.FormsCookieName, ticketString);

    HttpContext.Response.Cookies.Add(cookie);
}

最佳答案

这里的问题是 MVC 将在您的授权属性之前执行您的路由约束。我在这里面临的问题是我将路线定义为:

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

    routes.MapRoute(
        name: "ProjectEdit",
        url: "Projects/Edit/{id}",
        defaults: new { controller = "Projects", action = "Edit" },
        constraints: new { id = new IsValidProjectConstraint() }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}",
        defaults: new { controller = "Home", action = "Index" }
    );

    routes.MapRoute(
        name: "404-PageNotFound",
        url: "{*url}",
        defaults: new { controller = "Errors", action = "NotFound" }
    );
}

所以如果路由约束IsValidProjectConstraint()返回 false 然后操作 NotFound Controller Errors会执行。在这种情况下,它总是返回 false,因为在我的 User 时捕获到错误。对象为空。不幸的是我有 [AllowAnonymous]我的 Errors 上的属性允许呈现错误页面的 Controller ,因此似乎 MVC 没有执行我的 AuthorizeAttribute筛选。

关于asp.net-mvc - 路由约束破坏了授权属性过滤器 - MVC 4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15705566/

相关文章:

jquery - 我如何复制 stackoverflow 关闭按钮单击以替换 asp.net-mvc 中的确认页面

ASP.NET MVC5 身份定制

asp.net-mvc - Azure 网站中的 ASP.NET MVC4 + Ninject + NLog = 问题

.net - CaSTLe Windsor IoC 未将 log4net 注入(inject)我的 Controller

c# - 如何使用表单例份验证锁定用户

asp.net-mvc - 更改剑道数字过滤器格式

c# - 对于特定属性,您如何在 ModelState 中获取错误?

c# - MVC4 动态 Controller 路径?

c# - 登录状态不显示已登录

forms-authentication - Nancy:FormsAuthentication - 入门