在ASP.NET MVC中,您可以使用如下标记控制器方法AuthorizeAttribute:
[Authorize(Roles = "CanDeleteTags")]
public void Delete(string tagName)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
这意味着,如果当前登录的用户不在"CanDeleteTags"角色中,则永远不会调用控制器方法.
不幸的是,对于失败,AuthorizeAttribute返回HttpUnauthorizedResult,它总是返回HTTP状态代码401.这导致重定向到登录页面.
如果用户未登录,则这非常有意义.但是,如果用户已登录但未处于所需角色,则将其发送回登录页面会很困惑.
似乎AuthorizeAttribute将身份验证和授权混为一谈.
这似乎是ASP.NET MVC的一个疏忽,或者我错过了什么?
我不得不做一个DemandRoleAttribute将两者分开的东西.当用户未经过身份验证时,它会返回HTTP 401,并将其发送到登录页面.当用户登录但未处于所需角色时,它会创建一个NotAuthorizedResult.目前,这会重定向到错误页面.
当然我不必这样做?
我设计了一个控制器ErrorController,使用类似Forbiddenor 的方法调用NotFound,因此我可以将以下几行添加到 Web.config 中:
<customErrors mode="On" defaultRedirect="~/Error/Unknown" />
<error statusCode="404" redirect="~/Error/NotFound" />
<error statusCode="403" redirect="~/Error/Forbidden" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)
所以现在我希望能够做这样的事情:
public ActionResult Edit(int idObject)
{
if( user.OnwsObject(idObject) )
{
// lets edit
}
else
{
// ** SEND AN ERROR 403 ***
// And let ASP.NET MVC with IIS manage that error to send
// the requester to the Web.config defined error page.
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我尝试过类似的事情:(A)throw new HttpException(403, "Error description");:导致导致系统崩溃的未处理异常,(B)return HttpStatusResultCode(403, "Error description") …