有很多方法(大多数是自定义的),但我会使用默认的 MVC 功能并保持路由不变,而是根据安全角色有两个控制器操作:
// actions part of UserController
public ActionResult Index()
{
...
}
[Authorize(Roles = "admin")]
[ActionName("Index")]
[AdminsOnly]
public ActionResult IndexAdmin()
{
...
}
当用户成为特定角色的成员时,这将自动运行第二个。但是,如果您只有一个特定用户(管理员),那么您可以将该属性更改为:
[Authorize(Users = "admin")]
如果您使用一些自定义机制来定义用户类型/角色成员资格,您始终可以编写自己的授权操作过滤器。
但AuthoriseAttribute
不是动作选择器过滤器,因此 MVC 无法在不创建自定义动作选择器过滤器的情况下区分两者AdminsOnlyAttribute
。这会为您进行检查,并且您不会错误地认为请求有多个操作。在编写此自定义过滤器的情况下,您也可以简单地删除,AuthorizeAttribute
因为您的操作选择器已经检查过了。
其他竞争者
风俗Route
如果这不是您想要的,您始终可以编写自己的自定义Route
类,根据用户名/角色成员身份将用户重定向到特定区域......尽管重定向也可能是您Login
操作的一部分
[HttpPost]
public ActionResult Login(LoginCredentials user)
{
// authenticate
...
if (User.IsInRole("admin"))
{
return this.RedirectToAction("Index", "User", new { area = "Admin" });
}
return this.RedirectToAction("Index", "User");
}
此操作假定您的应用程序中有管理区域。
自定义路由约束
另一种可能性是有自定义路由约束。因此,您实际上会定义两条路线,但一条路线具有特定的约束:
routes.MapRoute(
"Admin", // Route name
"{controller}/{action}/{id}",
new { area = "Admin", controller = "User", action = "Index", id = UrlParameter.Optional },
new { isAdmin = new AdminRouteConstraint() }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "User", action = "Index", id = UrlParameter.Optional }
);
这样,您就可以将管理员路由到应用程序的管理区域,并为他们提供他们在那里拥有的特定功能。但这并不意味着他们需要一个管理区域。这只是我的路线定义。您可以按照您想要的方式定义路由默认值。