我正在尝试设置控制器上方法的默认访问权限,因此我在[Authorize]
上添加了ApiController
属性。
在大多数情况下,除非被[AllowAnonymous]
属性覆盖,否则这样可以正常工作。
现在我想在混音中添加另一个级别。对于默认情况下我的授权方法,我希望它们需要特定的角色(例如admin),因此我将控制器级别属性更新为[Authorize(roles="admin")]
。除了少数例外,我不关心它们是什么角色(只是经过身份验证就足够了)。
我认为我可以坚持在控制器级别设置Authorize属性并在单个方法级别覆盖它,但这似乎与[AllowAnonymous]
的工作方式不同。
有没有关于如何解决这个问题的建议,而不必记得用默认访问级别装饰每个新方法?像[Authorize(roles="*")]
这样的东西?即使我需要一个默认角色每个用户都是 AuthenticatedUsers 的一部分,那也没关系。
答案 0 :(得分:8)
如何创建标记属性? AllowAnonymous是一个这样的标记,BTW。当标记在那里时,创建您自己的Authorize属性并清除角色。
[MyAuth(Roles = "admin")]
public class ValuesController : ApiController
{
[ExemptRoles]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
public class ExemptRolesAttribute : Attribute { }
public class MyAuthAttribute : AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext.ActionDescriptor.GetCustomAttributes<ExemptRolesAttribute>().Any())
base.Roles = String.Empty;
base.OnAuthorization(actionContext);
}
}
答案 1 :(得分:1)
这基本上就是我正在做的事情。我创建了自定义AuthorizeAttribute
并覆盖了OnAuthorization
方法。
然后,我可以检查用户是否是当前自定义属性中标记的任何角色 如果没有,我将回归默认授权处理。
public class InternalAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if(actionContext == null)
throw new ArgumentNullException("actionContext");
if (AuthorizeRequest(actionContext))
return;
// no special authorization found. fall back to base (handles AllowAnonymous, and Controller level attribute)
base.OnAuthorization(actionContext);
}
private bool AuthorizeRequest(HttpActionContext actionContext)
{
if (!actionContext.ActionDescriptor.GetCustomAttributes<InternalAuthorizeAttribute>().Any())
return false;
foreach (AuthorizeAttribute attribute in actionContext.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>())
{
foreach (var role in attribute.Roles.Split(','))
{
if (HttpContext.Current.User.IsInRole(role)) return true;
}
}
return false;
}
}