在我们的MVC解决方案中,我们有两个AuthorizeAttribute
的自定义实现-一个名为BasicHttpAuthorizeAttribute
,已经在生产中使用了多年,而另一个RoleAuthorizeAttribute
,是最近添加的。
在创建RoleAuthorizeAttribute
时,我只复制了BasicHttpAuthorizeAttribute
并修改了一些已经被覆盖的方法。
这两个属性均用于验证用户身份,并RoleAuthorizeAttribute
用于验证用户是否具有所需角色。
但是,RoleAuthorizeAttribute
从不对用户进行身份验证。根本就不会调用它,相反,当非登录用户到达控制器操作并且代码请求上下文用户时,我们的MVC控制器会引发异常。
以下是此自定义AuthorizeAttribute
的概述。如果我在所有这些方法上都设置了断点,我发现在发出请求时都不会命中它们。
谁能解释为什么不使用此类来认证用户?为什么未通过身份验证的用户没有被重定向到登录页面,但是如果我将RoleAuthorize
换成BasicHttpAuthorize
或只是将基本Authorize
换成 重定向了吗?
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class RoleAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
/// <summary>
/// Gets or sets the <see cref="Role"/> enumerations required for authorization.
/// </summary>
public Role[] RequiredRoles
{
get {...}
set {...}
}
public bool RequireSsl { get; set; };
public bool RequireAuthentication { get; set; }
public RoleAuthorizeAttribute(params Role[] requiredRoles)
{
// ...
}
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
// ...
}
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
// ...
}
private bool Authenticate(System.Web.Http.Controllers.HttpActionContext actionContext)
{
// ...
}
public static bool TryGetPrincipal(string authHeader, out IPrincipal principal)
{
// ...
}
public static bool TryGetAuthCookie(out IPrincipal principal)
{
// ...
}
private static string[] ParseAuthHeader(string authHeader)
{
// ...
}
private static bool TryGetPrincipal(string username, string password, out IPrincipal principal)
{
// ...
}
}
这是其用法示例:
namespace MyProject.Areas.Customer.Controllers
{
[RoleAuthorize(Role.Customer, Role.CompanyAdmin)]
public partial class OrderController : MyCustomController
{
private static readonly ILog Log = LogManager.GetLogger(typeof (OrderController));
public ActionResult Index(int id)
{
// ...
}
}
}
我们使用基本身份验证,因此设置了标头:
我见过older questions asking about the same problem,但是在那些情况下,它们也覆盖了AuthorizeCore
类中似乎不再存在的AuthorizeAttribute
方法。
答案 0 :(得分:3)
我弄清楚了为什么会这样。
有两个AuthorizeAttributes
-一个在System.Web.Http
名称空间中,另一个在System.Web.Mvc
中。我没有意识到这一点,并试图建立一个“一刀切”的属性,因此我的属性可以用于WebAPI请求,但不能用于MVC控制器请求。
这两个属性的区别在于OnAuthorize
方法中,它们各自采用不同的上下文参数。
一旦我建立了两个独立的属性(几乎相同),每个属性都来自不同的AuthorizeAttribute
,一切都会按预期进行。