我对AuthorizeAttribute
;的默认行为感到相当惊讶 如果您不提供任何Roles
属性,它似乎只是允许任何授权用户访问控制器/操作。我想要白名单行为;如果Roles
为 null 或为空,则拒绝所有用户访问。我怎样才能使这种行为发生?
问问题
2761 次
2 回答
5
public class AuthorizeExAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (string.IsNullOrWhiteSpace(Roles))
return false;
return base.AuthorizeCore(httpContext);
}
}
现在[AuthorizeEx]
在你的控制器/动作上使用
于 2012-10-10T14:47:10.207 回答
3
这是我最终想出的,作为我添加到 MVC 应用程序的全局过滤器集合中的过滤器:
/// <summary>
/// This filter should be applied to an MVC application as a global filter in RegisterGlobalFilters, not applied to individual actions/controllers.
/// It will cause access to every action to be DENIED by default.
/// If an AllowAnonymousAttribute is applied, all authorization checking is skipped (this takes precedence over AuthorizeSafeAttribute).
/// If an AuthorizeSafeAttribute is applied, only the roles specified in AuthorizeSafeAttribute's Roles property will be allowed access.
/// </summary>
public sealed class AuthorizeSafeFilter : AuthorizeAttribute {
public override void OnAuthorization(AuthorizationContext filterContext) {
if (!string.IsNullOrEmpty(this.Roles) || !string.IsNullOrEmpty(this.Users)) {
throw new Exception("This class is intended to be applied to an MVC application as a global filter in RegisterGlobalFilters, not applied to individual actions/controllers. Use the AuthorizeSafeAttribute with individual actions/controllers.");
}
// Disable caching for this request
filterContext.HttpContext.Response.Cache.SetNoServerCaching();
filterContext.HttpContext.Response.Cache.SetNoStore();
// If AllowAnonymousAttribute applied, skip authorization
if (
filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) ||
filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)
) {
return;
}
// Backup original roles
string rolesBackup = this.Roles;
// Look for AuthorizeSafeAttribute roles
bool foundRoles = false;
string foundRolesString = null;
object[] actionCustomAttributes = filterContext.ActionDescriptor.GetCustomAttributes(false);
object[] controllerCustomAttributes = filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(false);
if (actionCustomAttributes.Any(attr => attr is AuthorizeSafeAttribute)) {
AuthorizeSafeAttribute foundAttr = (AuthorizeSafeAttribute)(actionCustomAttributes.First(attr => attr is AuthorizeSafeAttribute));
foundRoles = true;
foundRolesString = foundAttr.Roles;
}
else if (controllerCustomAttributes.Any(attr => attr is AuthorizeSafeAttribute)) {
AuthorizeSafeAttribute foundAttr = (AuthorizeSafeAttribute)(controllerCustomAttributes.First(attr => attr is AuthorizeSafeAttribute));
foundRoles = true;
foundRolesString = foundAttr.Roles;
}
if (foundRoles && !string.IsNullOrWhiteSpace(foundRolesString)) {
// Found valid roles string; use it as our own Roles property and auth normally
this.Roles = foundRolesString;
base.OnAuthorization(filterContext);
}
else {
// Didn't find valid roles string; DENY all access by default
filterContext.Result = new HttpUnauthorizedResult();
}
// Restore original roles
this.Roles = rolesBackup;
}
}
我还定义了这个属性:
/// <summary>
/// Represents an attribute that is used to restrict access by callers to an action method, in conjunction
/// with a global AuthorizeSafeFilter, DENYING all access by default.
/// </summary>
public class AuthorizeSafeAttribute : Attribute {
public string Roles { get; set; }
}
我适用AllowAnonymousAttribute
于我的登录操作/控制器和AuthorizeSafeAttribute
其他登录操作/控制器,但如果我忘记应用这些,默认情况下会拒绝访问。我希望 ASP.NET MVC 在默认情况下也能像这样安全。:-)
于 2012-10-16T09:38:09.883 回答