Route restriction aborts Authorized Attribute Filter - MVC 4

After adding a routing restriction, I noticed that when I navigate to the URL used by this routing restriction, my application no longer performs my authorization attribute filter.

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> 

After adding this routing restriction, going to http://myurl/Projects/Edit/1 in the new browser will actually display the page as if I had already been authenticated. However, when I remove the routing restriction and then go to http://myurl/Projects/Edit/1 I redirect to my login action as expected.

It seems that any route restriction, whether related to my custom route restriction or just a regular expression, is causing this problem.

Is there something I am missing here?

EDIT: I think I should mention how I issue my FormsAuthentication cookie. My application acts as a SAML service provider, in which a SAML response from an identity provider is sent to my consumer confirmation service. ACs parses the SAML response and validates it, and then issues an authentication ticket through the following code:

 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
source share
1 answer

The problem here is that MVC will fulfill your routing restrictions before your authorize attribute. The problem I ran into was that I had the following routes:

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

therefore, if the routing constraint IsValidProjectConstraint() returns false, then the NotFound action of the NotFound controller will be executed. In this case, it always returned false because an error was detected when my User object was null. Unfortunately, I had the [AllowAnonymous] attribute on my Errors controller, which allowed me to display an error page, so it seemed like MVC was not executing my AuthorizeAttribute filter.

+2
source

All Articles