我正在尝试扩展他的默认Web Api授权属性,以允许经过身份验证的用户访问一组操作,即使它们未在应用程序中注册(例如,他们没有角色).
public class AuthorizeVerifiedUsersAttribute : AuthorizeAttribute { ////// Gets or sets the authorized roles. /// public new string Roles { get { return base.Roles; } set { base.Roles = value; } } ////// Gets or sets the authorized users. /// public new string Users { get { return base.Users; } set { base.Users = value; } } private bool _bypassValidation; ////// Gets of sets a controller or an action as an authorization exception /// public virtual bool BypassValidation { get { Debug.WriteLine("get:" + TypeId.GetHashCode() + " " + _bypassValidation); return _bypassValidation; } set { Debug.WriteLine("set:" + TypeId.GetHashCode() + " " + value); _bypassValidation = value; } } protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) { if (HttpContext.Current.User.Identity.IsAuthenticated) { if (BypassValidation) { return true; } else { //return false if user is unverified } } return base.IsAuthorized(actionContext); } }
它被这样使用:
[AuthorizeVerifiedUsers] public class UserProfileController : ApiController { [AuthorizeVerifiedUsers(BypassValidation = true)] public bool Verify(string verificationCode) {} }
到目前为止,这个动作是唯一使用BypassValidation = true的动作.
出现此问题的原因是,即使"调试"窗口(在BypassValidation属性中使用)显示以下内容,操作的BypassValidation属性为false:
set:26833123 True set:39602703 True get:43424763 False get:43424763 False get:43424763 False //应该有"True"的电话...
我注意到两件事:
TypeId(属性的唯一标识符)在具有BypassValidation = true的调用和具有BypassValidation = false的调用之间是不同的.
id'43424763'没有相应的集合
有任何想法吗?
在此先感谢,Joao
Web API的工作方式是为父作用域调用authorize属性,在本例中为控制器,并且需要手动完成覆盖(动作的authorize属性)(如果我错了,请纠正我).
因此,解决方案可能如下所示:
public class AuthorizeVerifiedUsersAttribute : AuthorizeAttribute { (...) protected override bool IsAuthorized(HttpActionContext actionContext) { if (HttpContext.Current.User.Identity.IsAuthenticated) { //retrieve controller action's authorization attributes var authorizeAttributes = actionContext.ActionDescriptor.GetCustomAttributes<AuthorizeVerifiedUsersAttribute>(); //check controller and action BypassValidation value if (BypassValidation || actionAttributes.Count > 0 && actionAttributes.Any(x => x.BypassValidation)) { return true; } else { //return false if user is unverified } return base.IsAuthorized(actionContext); } }