今天实现自定义AuthorizeAttribute却遇到了AllowAnonymous属性失效的问题,即使我在控制器、方法上声明AllowAnonymous也依然无法匿名访问,全都需要登陆后才可访问。
namespace System.Web.Mvc { // 摘要: // 表示一个特性,该特性用于标记在授权期间要跳过 System.Web.Mvc.AuthorizeAttribute 的控制器和操作。 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public sealed class AllowAnonymousAttribute : Attribute { // 摘要: // 初始化 System.Web.Mvc.AllowAnonymousAttribute 类的新实例。 public AllowAnonymousAttribute(); } }
按理说声明了AllowAnonymous的控制器或者方法就无需进行身份验证了,这是为什么呢???一定要弄个明白。。。用反编译工具对System.Web.Mvc.dll进行查看,如下图:
bool flag = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true); if (flag) { return; }
flag为bool类型变量,调用filterContext.ActionDescriptor.IsDefined方法,接着看下IsDefined方法定义
// System.Web.Mvc.ActionDescriptor /// <summary>Determines whether one or more instances of the specified attribute type are defined for this member.</summary> /// <returns>true if <paramref name="attributeType" /> is defined for this member; otherwise, false.</returns> /// <param name="attributeType">The type of the custom attribute.</param> /// <param name="inherit">true to look up the hierarchy chain for the inherited custom attribute; otherwise, false.</param> /// <exception cref="T:System.ArgumentNullException">The <paramref name="attritubeType" /> parameter is null.</exception> public virtual bool IsDefined(Type attributeType, bool inherit) { if (attributeType == null) { throw new ArgumentNullException("attributeType"); } return false; }
该方法接收两个参数,第一个attributeType(自定义特性的类型),第二个参数inherit(要查找继承的自定义特性的层次结构链,则为 true;否则为 false),返回结果(如果为此成员定义了 attributeType,则为 true;否则为 false)。
再看看我自定义的AuthorizeAttribute实现,就不难理解为什么我的AllowAnonymous会失效了。哈哈~~,正如大家所想。只要在自定义AuthorizeAttribute实现里加上红色标注块里的代码,我们就可以再不需要进行授权的控制器或者方法上标注AllowAnonymous了。