添加路由约束后,我注意到当导航到应用此路由约束的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);
}
答案 0 :(得分:2)
这里的问题是MVC将在您的authorize属性之前执行路由约束。我在这里遇到的问题是我的路线定义为:
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
的操作Errors
将会执行。在这种情况下,它始终返回false,因为当User
对象为空时捕获了错误。不幸的是,我的[AllowAnonymous]
控制器上有Errors
属性,允许渲染错误页面,因此好像MVC没有执行我的AuthorizeAttribute
过滤器。