Divyay208 Ответов: 2

Как добавить динамический префикс к URL-адресу в MVC на основе ролей


В моем приложении я работаю с различными ролями пользователей, основываясь на роли, на которую я перенаправляю пользователя на контроллеры.

Теперь я хочу добавить префикс маршрута на основе ролей, как показано ниже

Если входящая в систему роль пользователя Admin, то URL-адрес должен быть:

http://localhost:/Admin/Home/Index[^]


Если роль зарегистрированного пользователя - "Пользователь", то URL-адрес должен быть

http://localhost:/User/Home/Index[^]


Как добавить эти пользовательские префиксы маршрутов на основе ролей в mvc


заранее спасибо

Что я уже пробовал:

На контроллере я добавил
[RoutePrefix("Admin/User")]
Это не работает, я хочу добавить этот префикс на основе ролей.

[CustomAuthorize("User", "Admin")]
[RoutePrefix("Admin/User")]
public class HomeController : SecureController
{
public actionresult Index()
{
return view();
}
}


здесь Если роль пользователя admin то префикс должен быть следующим http://localhost:/Admin/Home/Index[^]

2 Ответов

Рейтинг:
8

Divyay208

Я сделал переписывание URL-адреса, как показано ниже, и я могу добавить этот префикс для каждого контроллера.

Добавить ниже в фильтр авторизации

public override void OnAuthorization(AuthorizationContext filterContext)
       {
           var userRoleName = //GetUserRoleName;

           filterContext.RouteData.Values["role"] = userRoleName;
       }


Затем мы можем просто добавить Routeprefix на уровне контроллера после авторизации роли пользователя
[CustomAuthorize("Admin", "User")]
   [RoutePrefix("{role}")]
   public class HomeController : Controller
   {
   [Route]
   public ActionResult Index()
   {
   return View()
   }
   }


Рейтинг:
0

F-ES Sitecore

Нет никакой реальной ценности в этом, если вы хотите знать роль пользователя, а затем получить роль, когда вам нужно это знать, взяв ее из url-адреса, это проблема безопасности. Если вы просто хотите, чтобы он был на url-адресе для эстетики, то что-то вроде этого может помочь

Создание обработчика маршрута

public class UserRoleHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        // Work out the role here, I am hard-coding for simplicity
        string userRole = "Admin";

        requestContext.RouteData.Values["role"] = userRole;

        return new MvcHandler(requestContext);
    }
}


и обновите свое отображение маршрута по умолчанию следующим образом

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


Мы поставили параметр role первым, но пользовательский UserRoleHandler будет гарантировать, что значение роли-это та роль, в которой находится пользователь, а не то, что находится на url-адресе. Таким образом, даже если кто-то вручную изменит "пользователь" на "администратор", значение роли все равно будет пользователем, если это то, что они есть.

Выше приведен MVC 5, Вам может потребоваться настроить его по мере необходимости, если вы не используете 5.

Обновление

Исходный маршрут не будет работать с этой конфигурацией, если вы хотите, чтобы традиционный маршрут "контроллер/действие" работал, вы можете попробовать что-то вроде

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

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


Проблема с несколькими маршрутами, как описано выше, заключается в том, что при создании URL-адресов, если вы хотите специально иметь стандартный шаблон url-адресов, Вам нужно указать, что вы хотите использовать "традиционный" маршрут. Альтернативой является то, что вы оставляете значение по умолчанию таким, как оно есть, и используете значение с ролью не по умолчанию, но тогда каждый раз, когда вам нужен url-адрес в этом формате, вам нужно будет выбрать соответствующее имя маршрута при его создании.


Divyay208

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

F-ES Sitecore

Ваши пользователи имеют роли независимо от того, была ли еще вызвана авторизация. Это просто запрещает доступ к действию, если пользователь не находится в правильной роли, он фактически не назначает эту роль. Гугл Как получить список ролей пользователя.

Divyay208

Я реализовал то же самое, но я получаю ошибки в
публичный класс UserRoleHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
// Проработайте свою роль здесь, я жестко кодирую для простоты
ВАР listRoles = новый список<строка> У { "админ", "пользователь", "РРР" };

requestContext.RouteData.Values["role"] = listRoles;

возврат нового MvcHandler(requestContext);
}
}

Ошибка 'контроллер для индекса Path '/Домашний/' не найден или не реализует IController.'

F-ES Sitecore

Я обновил исходное решение

Divyay208

Спасибо за решение, я изменил свой код соответствующим образом, но он все еще не работает, может быть, он не будет работать таким образом, я обновил то, что я пробовал в вопросе. мое требование аналогично https://stackoverflow.com/questions/32764989/asp-net-mvc-5-culture-in-route-and-url

но это основано на современной культуре.