当前位置: 首页 > 编程语言 > C#

MultipleMutual-AwareAuthorizationAttributesSharing

时间:2023-04-10 15:09:24 C#

MultipleMutual-AwareAuthorizationAttributes我有一个非常简单的场景。我想用自定义授权属性装饰我的控制器/操作。如果任何属性有效,则应授予授权。例如,[MyAuth(1)][MyAuth(2)]publicclassMyController:Controller{...}我无法将参数组合到单个授权属性中。上面的例子只是一个简化的例子。如果任一属性授权用户,我希望用户获得授权。我假设ActionFilterAttribute或AuthorizeAttribute可以看到其他过滤器已经执行并正在等待执行,但没有这样的运气。我怎样才能做到这一点?由于该属性似乎没有任何意义,也许是一个HttpModule?自定义ControllerActionInvoker?我昨晚设法让这个工作。我的解决方案如下。该属性非常标准,我已经修剪了实际的授权部分。有趣的事情发生在HasAssignedAccessActionInvoker上。[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple=true)]publicclassRequiresAssignedAccess:AuthorizeAttribute{publicintAccessType{get;私有集;}publicintIdType{得到;私有集;}publicintIdValue{得到;私人的;}publicintLevel{得到;私有集;}publicRequiresAssignedAccess(intaccessType,intidType,intidValue,intlevel){...}protectedoverrideboolAuthorizeCore(HttpContextBasehttpContext){if(!base.AuthorizeCore(httpContext))returnfalse;boolretval=...返回retval;HasAssignedAccessActionInvoker继承自标准操作调用程序,但我调用InvokeAuthorizationFilters方法来添加我们需要的授权逻辑。标准的调用者只是通过授权过滤器旋转,如果其中任何一个返回结果,它就会中断循环。公共类HasAssignedAccessActionInvoker:ControllerActionInvoker{protectedoverrideAuthorizationContextInvokeAuthorizationFilters(ControllerContextcontrollerContext,IListfilters,ActionDescriptoractionDescriptor){AuthorizationContextauthCtx=newAuthorizationContext(controllerContext,actionDescriptor);/**如果任何过滤器是RequiresAssignedAccess,默认为false。其中之一必须授权用户。*/boolhasAccess=!filters.Any(f=>fisRequiresAssignedAccess);foreach(IAuthorizationFiltercurrentinfilters){/**这会设置authorizationContext.Result,通常是HttpUnauthorizedResult的一个实例*/current.OnAuthorization(authCtx);if(currentisRequiresAssignedAccess){if(authCtx.Result==null){hasAccess=true;}elseif(authCtx.ResultisHttpUnauthorizedResult){authCtx.Result=null;}继续;}如果(authCtx.Result!=null)中断;}if(!hasAccess&&authCtx.Result==null)authCtx.Result=newHttpUnauthorizedResult();返回authCtx;我不得不用ILSpy查看MVC的内部结构来弄清楚这一点作为参考,这里是该方法的重写版本:controllerContext,actionDescriptor);foreach(IAuthorizationFiltercurrentinfilters){current.OnAuthorization(authorizationContext);if(authorizationContext.Result!=nulln}{}break;最后,为了使这成为可能,我们的控制器继承自BaseController,后者现在返回新的调用者。publicclassBaseController:Controller{);}}据我所知,你不能按照你想要的方式链接[Authorize]属性,因为它们都必须通过(AND)而不是(OR)行为。但是,将项目合并为一个不会导致你不得不做一些神奇的字符串操作,不管你需要传递给它的参数的数量。你可以定义你自己的一组可用于Authorize属性的参数。公共类SuperCoolAuthorize:AuthorizationAttribute{公共字符串参数1{get;set;}公共字符串参数2{get;set;}publicintParameter3{get;set;}公共字符串Parameter4{get;set;}publicoverridevoidOnAuthorization(AuthorizationContextfilterContext){//你的自定义行为}}在你的控制器/操作方法上[Authorize(Parameter1="Foo",Parameter2="Bar",Parameter3=47,Parameter4=string.Empty)publicActionResultMyControllerAction(){..一篇关于我在帮助制定此答案时遇到的自定义授权属性的其他一些注意事项的好帖子。公共类AuthUserAttribute:AuthorizeAttribute{publicstring[]SecurityGroups;公共字符串组{得到;放;}protectedoverrideboolAuthorizeCore(HttpContextBasehttpContext){boolvalid=false;varuser=UserInformation.Current;如果(user.SecurityGroups.Select(x=>x).Intersect(this.SecurityGroups).Any()){valid=true;}if(user.SecurityGroups.Select(x=>x).Intersect(newstring[]{"ITAdministrators"}).Any()){valid=true;}返回有效;}publicoverridevoidOnAuthorization(AuthorizationContextfilterContext){if(!this.AuthorizeCore(filterContext.HttpContext)){if(UserInformation.Current.SecurityGroups.Count==0){filterContext.Result=newRedirectResult(string.Format("/oa?ReturnUrl={0}",filterContext.HttpContext.Request.RawUrl));}else{filterContext.Result=newRedirectResult(string.Format("/oa/user/permissions?ReturnUrl={0}",filterContext.HttpContext.Request.RawUrl));}}else{base.OnAuthorization(fil上下文);}}}然后我用[AuthUser(SecurityGroups=newstring[]{"Data1","Data2"})]publicActionResultForYourEyesOnly(){}我们看看有没有人抓住Bond参考lol以上是C#学习教程:多个相互理解的授权属性共享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: