幼儿饰品瑜伽美体用品微软
投稿投诉
微软创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品

SpringSecurity中的权限注解很神奇吗?

  最近有个小伙伴在微信群里问SpringSecurity权限注解的问题:
  很多时候事情就是这么巧,松哥最近在做的tienchin也是基于注解来处理权限问题的,所以既然大家有这个问题,咱们就一块来聊聊这个话题。
  当然一些基础的知识我就不讲了,对于SpringSecurity基本用法尚不熟悉的小伙伴,可在公众号后台回复ss,有原创的系列教程。1。具体用法
  先来看看SpringSecurity权限注解的具体用法,如下:PreAuthorize(ss。hasPermi(tienchin:channel:query))GetMapping(list)publicTableDataInfogetChannelList(){startPage();ListChannellistchannelService。list();returngetDataTable(list);}
  类似于上面这样,意思就是说,当前用户需要具备tienchin:channel:query权限,才能执行当前的接口方法。
  那么要搞明白PreAuthorize注解的原理,我觉得得从两个方面入手:首先明白Spring中提供的SpEL。其次搞明白SpringSecurity中对方法注解的处理规则。
  我们一个一个来看。2。SpEL
  SpringExpressionLanguage(简称SpEL)是一个支持查询和操作运行时对象导航图功能的强大的表达式语言。它的语法类似于传统EL,但提供额外的功能,最出色的就是函数调用和简单字符串的模板函数。
  SpEL给Spring社区提供一种简单而高效的表达式语言,一种可贯穿整个Spring产品组的语言。这种语言的特性基于Spring产品的需求而设计,这是它出现的一大特色。
  在我们离不开Spring框架的同时,其实我们也已经离不开SpEL了,因为它太好用、太强大了,SpEL在整个Spring家族中也处于一个非常重要的位置。但是很多时候,我们对它的只了解一个大概,其实如果你系统的学习过SpEL,那么上面SpringSecurity那个注解其实很好理解。
  我先通过一个简单的例子来和大家捋一捋SpEL。
  为了省事,我就创建一个SpringBoot工程来和大家演示,创建的时候不用加任何额外的依赖,就最最基础的依赖即可。
  代码如下:StringexpressionStr12;ExpressionParserparsernewSpelExpressionParser();Expressionexpparser。parseExpression(expressionStr);
  expressionStr是我们自定义的一个表达式字符串,这个字符串通过一个ExpressionParser对象将之解析为一个Expression,接下来就可以执行这个exp了。
  执行的时候有两种方式,对于我们上面这种不带任何额外变量的,我们可以直接执行,直接执行的方式如下:Objectvalueexp。getValue();System。out。println(value。toString());
  这个打印结果为3。
  我记得之前有个小伙伴在群里问想执行一个字符串表达式,但是不知道怎么办,js中有eval函数很方便,我们Java中也有SpEL,一样也很方便。
  不过很多时候,我们要执行的表达式可能比较复杂,这时候上面这种调用方式就不太够用了。
  此时我们可以为要调用的表达式设置一个上下文环境,这个时候就会用到EvaluationContext或者它的子类,如下:StandardEvaluationContextcontextnewStandardEvaluationContext();System。out。println(exp。getValue(context));
  当然上面这个表达式不需要设置上下文环境,我举一个需要设置上下文环境的例子。
  例如我现在有一个User类,如下:publicclassUser{privateIntegerid;privateStringusername;privateStringaddress;省略gettersetter}
  现在我的表达式是这样:Stringexpressionuser。username;ExpressionParserparsernewSpelExpressionParser();Expressionexpparser。parseExpression(expression);StandardEvaluationContextctxnewStandardEvaluationContext();UserusernewUser();user。setAddress(广州);user。setUsername(javaboy);user。setId(99);ctx。setVariable(user,user);Stringvalueexp。getValue(ctx,String。class);System。out。println(valuevalue);
  这个表达式就表示获取user对象的username属性。将来创建一个user对象,放到StandardEvaluationContext中,并基于此对象执行表达式,就可以打印出来想要的结果。
  如果我们将user对象设置为rootObject,那么表达式中就不需要user了,如下:Stringexpressionusername;ExpressionParserparsernewSpelExpressionParser();Expressionexpparser。parseExpression(expression);StandardEvaluationContextctxnewStandardEvaluationContext();UserusernewUser();user。setAddress(广州);user。setUsername(javaboy);user。setId(99);ctx。setRootObject(user);Stringvalueexp。getValue(ctx,String。class);System。out。println(valuevalue);
  表达式就一个username字符串,将来执行的时候,会自动从user中找到username的值并返回。
  当然表达式也可以是方法,例如我在User类中添加如下两个方法:publicStringsayHello(Integerage){returnhellousername;ageage;}publicStringsayHello(){returnhellousername;}
  我们就可以通过表达式调用这两个方法,如下:
  调用有参的sayHello:StringexpressionsayHello(99);ExpressionParserparsernewSpelExpressionParser();Expressionexpparser。parseExpression(expression);StandardEvaluationContextctxnewStandardEvaluationContext();UserusernewUser();user。setAddress(广州);user。setUsername(javaboy);user。setId(99);ctx。setRootObject(user);Stringvalueexp。getValue(ctx,String。class);System。out。println(valuevalue);
  就直接写方法名然后执行就行了。
  调用无参的sayHello:StringexpressionsayHello;ExpressionParserparsernewSpelExpressionParser();Expressionexpparser。parseExpression(expression);StandardEvaluationContextctxnewStandardEvaluationContext();UserusernewUser();user。setAddress(广州);user。setUsername(javaboy);user。setId(99);ctx。setRootObject(user);Stringvalueexp。getValue(ctx,String。class);System。out。println(valuevalue);
  这些就都好懂了。
  甚至,我们的表达式也可以涉及到Spring中的一个Bean,例如我们向Spring中注册如下Bean:Service(us)publicclassUserService{publicStringsayHello(Stringname){returnhelloname;}}
  然后通过SpEL表达式来调用这个名为us的bean中的sayHello方法,如下:AutowiredBeanFactorybeanFactory;TestvoidcontextLoads(){Stringexpressionus。sayHello(javaboy);ExpressionParserparsernewSpelExpressionParser();Expressionexpparser。parseExpression(expression);StandardEvaluationContextctxnewStandardEvaluationContext();ctx。setBeanResolver(newBeanFactoryResolver(beanFactory));Stringvalueexp。getValue(ctx,String。class);System。out。println(valuevalue);}
  给配置的上下文环境设置一个bean解析器,这个bean解析器会自动跟进名字从Spring容器中找打响应的bean并执行对应的方法。
  当然,关于SpEL的玩法还有很多,我就不一一列举了。这里主要是想让小伙伴们知道,有这么个技术,方便大家理解PreAuthorize注解的原理。3。PreAuthorize
  接下来我们就回到SpringSecurity中来看PreAuthorize注解。
  权限的实现方式千千万,又有各种不同的权限模型,然而归结到代码上,无非两种:基于URL地址的权限处理基于方法注解的权限处理
  松哥之前的vhr使用的是前者。
  PreAuthorize注解当然对应的是后者。这次做的tienchin项目就是后者,我们来看一个例子:PreAuthorize(ss。hasPermi(tienchin:channel:query))GetMapping(list)publicTableDataInfogetChannelList(){startPage();ListChannellistchannelService。list();returngetDataTable(list);}
  注解好说,里边的ss。hasPermi(tienchin:channel:query)是啥意思呢?ss是一个注册在Spring容器中的bean,对应的类位于org。javaboy。tienchin。framework。web。service。PermissionService中。很明显,hasPermi就是这个类中的方法。
  这个hasPermi方法的逻辑其实很简单:publicbooleanhasPermi(Stringpermission){if(StringUtils。isEmpty(permission)){returnfalse;}LoginUserloginUserSecurityUtils。getLoginUser();if(StringUtils。isNull(loginUser)CollectionUtils。isEmpty(loginUser。getPermissions())){returnfalse;}returnhasPermissions(loginUser。getPermissions(),permission);}privatebooleanhasPermissions(SetStringpermissions,Stringpermission){returnpermissions。contains(ALLPERMISSION)permissions。contains(StringUtils。trim(permission));}
  这个判断逻辑很简单,就是获取到当前登录的用户,判断当前登录用户的权限集合中是否具备当前请求所需要的权限。具体的判断逻辑没啥好说的,就是看集合中是否存在某个字符串。
  那么这个方法是在哪里调用的呢?
  大家知道,SpringSecurity中处理权限的过滤器是FilterSecurityInterceptor,所有的权限处理最终都会来到这个过滤器中。在这个过滤器中,将会用到各种投票器、表决器之类的工具,这里我就不细说了,之前的SpringSecurity系列教程都有详细介绍。
  在投票器中,我们可以看到专门处理PreAuthorize注解的类PreInvocationAuthorizationAdviceVoter,我们来看下他里边的核心方法:Overridepublicintvote(Authenticationauthentication,MethodInvocationmethod,CollectionConfigAttributeattributes){PreInvocationAttributepreAttrfindPreInvocationAttribute(attributes);if(preAttrnull){returnACCESSABSTAIN;}returnthis。preAdvice。before(authentication,method,preAttr)?ACCESSGRANTED:ACCESSDENIED;}
  框架的源码写的就是好,你一看名字就知道他想干嘛了!这里就进入到最后一句,调用了一个Advice中到前置通知,来判断权限是否满足:publicbooleanbefore(Authenticationauthentication,MethodInvocationmi,PreInvocationAttributeattr){PreInvocationExpressionAttributepreAttr(PreInvocationExpressionAttribute)attr;EvaluationContextctxthis。expressionHandler。createEvaluationContext(authentication,mi);ExpressionpreFilterpreAttr。getFilterExpression();ExpressionpreAuthorizepreAttr。getAuthorizeExpression();if(preFilter!null){ObjectfilterTargetfindFilterTarget(preAttr。getFilterTarget(),ctx,mi);this。expressionHandler。filter(filterTarget,preFilter,ctx);}return(preAuthorize!null)?ExpressionUtils。evaluateAsBoolean(preAuthorize,ctx):true;}
  现在,当你看到这个before方法的时候,应该会觉得比较熟悉了吧。首先获取到preAttr对象,这个对象里边其实就保存着你PreAuthorize注解中的内容。接下来跟进当前登录用户信息authentication创建一个上下文对象,此时创建出来的上下文对象中就包含了当前用户具备哪些权限。获取过滤器(我们这个项目中无)。获取到权限注解。最后执行表达式,去查看当前用户权限中是否包含请求所需要的权限。
  就这样,是不是很简单?
  好啦,今天就和小伙伴们分享这么多,在松哥近期推出的tienchin项目视频中,也会通过视频的形式跟大家细聊这个知识点。

足球拖着尾巴,球员带着光芒?绍兴的王先生反映,他家的新电视机看起来很吃力,比如看球赛,运动员身上有光环、足球拖着尾巴。【1818黄金眼】运动员身上有光环,静止时就没有了?王先生介绍,去年11月……章泽天怎么突然变样了!拎5千包参加晚宴,脸颊瘦凹陷面相都变了针对不同的场合,身份的变化在着装方面会有适当的考虑。对于公众人物来说,我在公开正式的场合当中,造型的得体性为首要考虑的因素。作为京东的总裁夫人,章泽天经常奔波于各种正式的场合里……孟晚舟又被曝新消息,业内知情人士透露,4月1日身份将有新变化【孟晚舟又被曝新消息,业内知情人士透露,4月1日将当值华为董事长】熟悉孟晚舟是从她在加拿大被软禁开始。本是再正常不过的一场工作出差转机,结果却被软禁在了加拿大,而且长达1……实用才是王道,技嘉RTX3070VISIONOC雪鹰,性价比随着显卡价格的回落,PC市场也开始逐渐回温。也正是因为生产力的需求,刚好也让我有了升级显卡的念头。考虑到预算和白色机箱环境,可挑选的范围也就大大缩小了。经过一系列白色显卡……和爸爸妈妈一起集福打卡寻兔子,舟山路幼儿园萌娃游戏中开学钱江晚报小时新闻记者高华生通讯员万东乐听说幼儿园开学现场来了几只新年兔子,孩子们开心地和爸爸妈妈一起集福打卡玩嗨了。这是杭州市舟山路幼儿园星星园区2月7日新学期开学……阿克塞钦的战略地位有多重要,俯瞰克什米尔地区,看守西大门1962年11月21日中印战争结束后,许多人对中国没有提任何条件就撤退到传统防线,并放弃藏南很不理解,但没有注意的是,有一个地方却牢牢地控制在我们的手里,那就是阿克赛钦地区,为……江西赣州购房契税补贴政策延续至2023年6月30日据赣州发布微信公众号消息,为进一步提振房地产消费信心,激发房地产消费潜能,促进房地产行业良性循环和健康发展,赣州市政府近期同意将章贡区、赣州经开区、蓉江新区享受契税补贴的购房时……精品游线路推荐!高明新春烟火季让你玩够本新春游玩线路高明烟火,四季有你!这些统统都能在佛山高明实现这个春节,欢迎大家来佛山高明过新年!高明烟火,四季有你!精品游玩线路推荐高明……NothingPhone,只能说是一网红手机罢了话说机友们有没有出去玩呢?机哥出去玩了。去的是长沙。既然是长沙,那大名鼎鼎的网红奶茶茶颜悦色,机哥我肯定是喝了滴而且一买,就是7杯。虽说味道,并没……詹姆斯古恩扎导支持DC宇宙重启Netflix没兴趣买扎导宇宙时光网讯DC影业联合CEO詹姆斯古恩前不久宣布了DC宇宙重启计划,2025年7月11日上映的《超人:传承》将成为开篇之作。近日他在社交媒体回答网友提问时表示,扎克施奈德有他和聊……这碗排骨饭,22年来圈粉无数东莞人!没地方停车都要来吃这家在道滘中心小学附近的早餐店凭借一碗排骨饭被街坊称赞了22年口碑爆棚一碗排骨饭,令人追随22年早餐店连招牌都没有挂,老板娘笑着说:其实店叫友谊早……敏感肌肤有救了!用这4款护肤产品,让你的皮肤恢复光泽作为敏感肌肤的拥有者,我们都知道它是多么难以打理。事实上,敏感肌肤不仅容易出现红肿、干燥、刺痛等症状,而且还有可能导致皮肤病变。那么,敏感肌肤到底是怎么产生的呢?其实,敏……
吉祥三宝消失14年后爸爸逝世,妈妈隐退,女儿英格玛模样大变历年的春晚节目上出现了很多优秀的作品,当然还有一个节目,在那一年火遍了大江南北2006年的《吉祥三宝》。相信至今大家都会演唱,且传唱程度十分的广泛。如今已经14年过……酒店水床有啥好处?为何深受情侣喜爱,前台非常实用旅游业的快速发展,也带动了相关产业的发展,比如说酒店行业,为了满足不同消费者的需求,酒店行业也是不断地在推陈出新,以吸收更多的客源,水床的发明与应用,就是酒店行业的一大创新。……西方艺术鉴赏克里姆特黄金之吻如果我们用一幅画被复制的数量作为衡量标准的话,那么今天我们就要讲到一幅旷世绝作《吻》,奥地利维也纳美景宫里,这幅《吻》被人群围得水泄不通,《吻》的衍生品丰富多彩,小到钥匙扣,T……洪水泛滥,美国黄石公园34年来首次关闭当地时间2022年6月13日,美国蒙大拿州,黄石国家公园加德纳河水位上涨,冲垮了一部分道路。美国黄石国家公园13日遭洪水侵袭,路桥毁坏,电力中断,游客撤离,公园所有5个入……从梦华录里活的宋韵想到的要问近来哪部剧全网最热,《梦华录》无疑能上榜。自开播以来,该剧成为各大社交平台热搜榜的常客,豆瓣评分一度奔8。8,成为年度现象级热剧。虽然随着剧情的发展,围绕该剧的争议不……港圈女神婚纱神图大赏,个个惊艳四座,她们的美无法复刻港圈女神婚纱神图大赏,个个惊艳四座,她们的美无法复刻!在香港影视蓬勃发展的年代,一批又一批的港圈女神横空出世,赏心悦目,点亮荧幕,当这些女神们穿上婚纱的时候,更是个个堪称……这六家公司散户正在疯狂出逃,但外资却在大举加仓如果你想在四月打赢一场漂亮的投资翻身仗,那么这六家公司我都真心建议你加入到自选,因为我发现他们散户正在疯狂出逃,但外资却在大举加仓。众所周知,主力在拉升抑制个股之前,通常……苹果又要放弃老机型,iOS17将不支持3GB内存设备,你的老WWDC即将在6月召开,苹果将正式公布iOS、iPadOS17系统,目前有关iOS17的设计细节已经被大量曝光。新系统将会带来一些重要的变化,例如控制中心和搜索体验会有大……浙江婺城春日苗农忙行商变坐商盆景变风景天气放晴,村民忙于苗木养护。田双双摄中新网金华4月14日电(董易鑫曹静怡)近日春光好,刚种下去上百株苗木,等待六月嫁接起来,开出来的花可漂亮了。近日,浙江金华婺城区罗店镇……菏泽凉皮寒了心,老百姓要的不是退15元,是有德的商家最近,菏泽凉皮事件在网上引起了轩然大波。一名游客在牡丹园景区买了一份15元的凉皮,发现味道不对,要求退货,却遭到商家的拒绝和辱骂。据说,菏泽牡丹园耗资十个亿打造,宣……午子寻茶午子寻茶文王印明每个人都有自己喜欢的味道。多年前,应文友之邀,品尝了一杯午子仙毫,满口生香,直透心底。从此,我便与茶结缘,怎么也忘不了那沁心的香味。闲下来时品一杯香……又进一步!华为公布量子芯片专利,能节省很多芯片一群孤独创业的中年人团队,欢迎志同道合的同志讨论分享心得近段时间,华为余承东公布了一项量子芯片和量子计算机相关专利,据说这项技术可以大大提高量子芯片的良品率,并降低其制作……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网