ASP.NET Routing: редиректы и безопасность

Программирование

Tagged Under : , ,

Недавно задали вопрос относительно предопределённых редиректов для добавляемого маршрута. Поясню о чём речь. В качестве примера попробуйте перейти по ссылке dfm. Как покажет Firebug нас оттуда перекинуло на подраздел «Новости», хотя вполне может перекинуть и на «Ивенты» или другой подраздел – все зависит от редакторов. Там стоит редирект.

Собственно, давайте разберёмся как сделать такое же используя routing и для чего применяемый подход может пригодится ещё.

Впринципе, всё просто. Действуем по стандартной схеме: создаем метод по регистрации маршрутов и вызываем его. Картинка первоначально такая:

private void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("test with handler", "test/", "~/default.aspx", false, null, null, null);
}

protected void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes(RouteTable.Routes);
}

Это добавляем в Global.asax.[/cc]
Ну, а теперь подумаем как нам сделать редирект, test – наш аналог press у dfm. Можно в Defaults маршрута запихнуть данные о том куда произвести редирект и на самой странице уже всё сделать, аналогично, для MVC это будет метод некоего вспомогательного контроллера. И в том и в другом случае мы сможем сделать обработку редиректов общей: для разных разделов понадобится либо одна страница либо один Action контроллера.
Но писалось всё это для второго способа, в котором мы будем использовать наследника интерфейса IRouteHandler и свойство маршрута (Route) RouteHandler.
Добавим к проекту следующие два класса

    public class TestRouteHandler: IRouteHandler
    {
        string _redirectUrl = string.Empty;
        public TestRouteHandler(string redirectUrl)
        {
            _redirectUrl = redirectUrl;
        }

        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new TestHttpHandler(_redirectUrl);
        }        
    }

    public class TestHttpHandler : IHttpHandler
    {
        string _redirectUrl = string.Empty;
        public TestHttpHandler(string redirectUrl)
        {
            _redirectUrl = redirectUrl;
        }

        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            if (!string.IsNullOrEmpty(_redirectUrl))
                context.Response.Redirect(_redirectUrl);            
        }
    }

А потом модифицируем код в Global.asax таким образом

private void RegisterRoutes(RouteCollection routes)
{
    Route route = routes.MapPageRoute("test with handler", "test/", "~/default.aspx", false, null, null, null);
    route.RouteHandler = new TestRouteHandler("/test.aspx");            
}

В результате нас кинет на страницу test.aspx, впринципе переадресовать можно и на какой-то маршрут, если использовать context.Response.RedirectToRoute, но тогда и передавать надо немного другое, но принцип тот же и мало отличается, поэтому примера для этого случая приводить не буду.

Решение смотрится элегантнее, к тому же по такому принципу можно не только организовать переадресацию, но и обезопасить доступ к некоторым разделам сайта, например проверить входит ли пользователь в группу администраторов.
Такой подход может стать очень выгодным в том плане, что работа с безопасностью для определённых маршрутов будет сосредоточена в таком вот хендлере и в методе регистрации маршрутов, что смотрится гораздо удобнее чем делать тоже самое через аттрибуты, которые используются для различных контроллеров и различных экшенов и могут быть сильно разбросаны по файлам проекта.




Оставить комментарий