制作AuthorizeAttribute默认情况下拒绝用户如果角色是空的 [英] Making AuthorizeAttribute deny users by default if Roles is empty

查看:908
本文介绍了制作AuthorizeAttribute默认情况下拒绝用户如果角色是空的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 AuthorizeAttribute 默认行为颇为惊讶;如果你不提供任何角色属性,它只是似乎允许的任何的授权用户访问控制器/动作。我想白名单,而不是行为;如果角色为null或空,拒绝的所有用户的访问。我怎样才能让这种行为出现?

I'm rather surprised at the default behaviour of AuthorizeAttribute; if you don't supply it any Roles property, it just appears to allow any authorized user to access the controller/action. I want whitelist behaviour instead; if Roles is null or empty, deny all users access. How can I make this behaviour occur?

推荐答案

这就是我想出了最后,作为一个过滤器我添加到全局过滤器集合MVC应用程序:

Here's what I came up with eventually, as a filter I add to the global filter collection for an MVC application:

/// <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;
    }
}

我也定义此属性:

I also define this attribute:

/// <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分别为这是默认安全​​。 : - )

I apply AllowAnonymousAttribute to my login actions/controllers and AuthorizeSafeAttribute to other ones, but if I forget to apply these, access is denied by default. I wish ASP.NET MVC were as secure as this by default. :-)

这篇关于制作AuthorizeAttribute默认情况下拒绝用户如果角色是空的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆