4

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

过滤器配置文件

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

项目控制器.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);
    }
}

路由配置.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;
        }
    }
}

网络配置

<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);
}
4

1 回答 1

2

这里的问题是 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" }
    );
}

so if the routing constraint IsValidProjectConstraint() returned false then action NotFound of controller Errors would execute. In this case it was always returning false because an error was caught when my User object was null. Unfortunately I had [AllowAnonymous] attribute on my Errors controller which allowed for an error page to render, so it seemed as if MVC was not executing my AuthorizeAttribute filter.

于 2013-04-01T15:46:25.373 回答