首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用IAuthorizationFilter检查声明--“找不到合适的类型构造函数”

使用IAuthorizationFilter检查声明--“找不到合适的类型构造函数”
EN

Stack Overflow用户
提问于 2020-03-28 00:22:34
回答 1查看 678关注 0票数 1

我正在尝试使用IAuthorizationFilter实现检查索赔。有了下面的代码,它就可以正常工作了-

代码语言:javascript
复制
    public class ClaimsAttribute : TypeFilterAttribute
    {
        public ClaimsAttribute(string claimType, string claimValue) : base(typeof(ClaimsFilter))
        {
            this.Arguments = new object[] { new Claim(claimType, claimValue) };
        }
    }

    public class ClaimsFilter : IAuthorizationFilter
    {
        private readonly Claim _claim;

        public ClaimsFilter(Claim claim)
        {
            _claim = claim;
        }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var hasClaim = context.HttpContext.User.Claims.Any(p => p.Type == _claim.Type && p.Value == _claim.Value);
            if (!hasClaim)
            {
                context.Result = new ForbidResult();
            }
        }
    }

    public class DocumentController : Controller
    {
        [Claims(AppClaimTypes.Permission, "CanReadDocument")]
        [HttpGet]
        public ActionResult GetDocument()
        {
            return View();
        }
    }

所以我想,我也可以检查一下多个索赔值-

代码语言:javascript
复制
    public class Claims2Attribute : TypeFilterAttribute
    {
        public Claims2Attribute(string claimType, params string[] claimValues) : base(typeof(Claims2Filter))
        {
            this.Arguments = new object[claimValues.Length];
            for (int i = 0; i < claimValues.Length; i++)
            {
                this.Arguments[i] = new Claim(claimType, claimValues[i]);
            }
        }
    }

    public class Claims2Filter : IAuthorizationFilter
    {
        private readonly Claim[] _claims;

        public Claims2Filter(Claim[] claims)
        {
            _claims = claims;
        }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            bool hasClaim = false;
            foreach (var item in _claims)
            {
                hasClaim = context.HttpContext.User.Claims.Any(p => p.Type == item.Type && p.Value == item.Value);
                if (hasClaim)
                    break;
            }

            if (!hasClaim)
            {
                context.Result = new ForbidResult();
            }
        }
    }

    public class DocumentController : Controller
    {
        [Claims2(AppClaimTypes.Permission, "CanReadSecretDocument", "SecretAccess")]
        [HttpGet]
        public ActionResult GetSecretDocument()
        {
            return View();
        }
    }

但现在它抛出了错误-

InvalidOperationException:无法找到“AuthorizationFilterTest.Claims2Filter”类型的合适构造函数。确保类型是具体的,并为公共构造函数的所有参数注册服务。

我认为这与注册服务没有任何关系,否则第一个版本就行不通。它似乎更琐碎/愚蠢,但我找不到它。

我做错什么了?

EN

回答 1

Stack Overflow用户

发布于 2020-03-29 15:22:28

这是关于如何传递参数以实例化目标IAuthorization类型(在本例中为Claims2Filter)。

如果Arguments属性(是一个对象数组)包含多个元素,那么每个元素都被认为是一个不同的参数,可以传递给目标IAuthorization类型的构造函数的一个不同的参数。换句话说,需要在Argument中的元素数和构造函数参数的数量之间进行一对一的映射。

因此,当Arguments包含两个Claim时,运行时实际上期望Claims2Filter具有以下构造函数-

代码语言:javascript
复制
    public ClaimsFilter(Claim claim1, Claim claim2)
    {
            //
    }

若要使用接受单个参数(即索赔对象数组)的构造函数( IAuthorization类型的构造函数),Arguments属性( TypeFilterAttribute类型的)应该包含一个元素,该元素是Claim数组。

所以,下面的变化让一切都像预期的那样运转-

代码语言:javascript
复制
    public class Claims2Attribute : TypeFilterAttribute
    {
        public Claims2Attribute(string claimType, params string[] claimValues) : base(typeof(Claims2Filter))
        {
            var claims = new Claim[claimValues.Length];
            for (int i = 0; i < claimValues.Length; i++)
            {
                claims[i] = new Claim(claimType, claimValues[i]);
            }

            this.Arguments = new object[] { claims };
        }
    }

我希望解释得足够清楚。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60895843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档