Как принудительно использовать значения маршрута Url в конвейере MVC в многопользовательском приложении

#asp.net-mvc #asp.net-mvc-4

#asp.net-mvc #asp.net-mvc-4

Вопрос:

У меня следующий маршрут по умолчанию

 url: "{tenant}/{controller}/{action}/{id}",
defaults: new { tenant="not_set", controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { tenant= new TenantConstraint()}
 

У меня есть user1, к которому должен быть доступ только tenant1/{Controller}/{action} .
Если пользователь пытался взломать URL tenantNoAccess/{Controller}/{action} , я хочу, чтобы он был автоматически перенаправлен tenant1/{Controller}/{action} .

Я могу сделать это в ActionFilter, но я не хочу, чтобы запрос продвигался так далеко вперед в конвейере mvc. Я хочу что-то сделать до того, как запрос попытается выполнить MapRequestHandler() .

Я подумал, может быть, в Application_PostAuthenticateRequest()?… У меня есть следующее в случае

 protected void Application_AuthenticateRequest(object o, EventArgs args)
{
    var context = HttpContext.Current;
    var httpContext = new HttpContextWrapper(HttpContext.Current);
    var user = context.User;
    var request = context.Request;
    var requestUrl = request.Url;
    var reqContext = request.RequestContext;

    if (user.Identity.IsAuthenticated)
    {
            var usr = (System.Security.Claims.ClaimsPrincipal)user;
            string correctTenant = GetCorrectTenantForUser(usr);
            if (!reqContext.RouteData.Values["tenant"].Equals(correctTenant))
            {
                //stuck here. How to change the URL without referencing a 3rd party Url rewrite module?
            }
            else 
            {
                //tenant matches
                return;
            }
    }
    else
    {
      //
    }
}
 

Ответ №1:

В RouteConfig вы можете добавить обработчик маршрута.

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

В routehandler вы можете выполнить необходимые проверки и установить соответствующий контроллер, действие, …..

 public class LandingPageRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext Context)
    {
        if ( <perform checks)
        {
            Context.RouteData.Values["controller"] = <whateveryouwant>;
            Context.RouteData.Values["action"] = <whateveryouwant>; 
            Context.RouteData.Values["id"] = <whateveryouwant>;
        }
        return base.GetHttpHandler(Context);
    }
}
 

Комментарии:

1. При таком подходе URL-адрес в адресной строке остается website.com/tenantNoAccess . Я хочу, чтобы пользователь перенаправлялся на website.com/tenant1 к которому пользователь имеет доступ. Есть ли способ добиться этого?