应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

如何利用自定义注解放行SpringSecurity项目的接口

  来源:blog。csdn。netweixin45089791articledetails118890274
  在实际项目中使用到了springsecurity作为安全框架,我们会遇到需要放行一些接口,使其能匿名访问的业务需求。但是每当需要当需要放行时,都需要在security的配置类中进行修改,感觉非常的不优雅。
  例如这样:
  所以想通过自定义一个注解,来进行接口匿名访问。在实现需求前,我们先了解一下security的两种方行思路。
  第一种就是在configure(WebSecurityweb)方法中配置放行,像下面这样:Overridepublicvoidconfigure(WebSecurityweb)throwsException{web。ignoring()。antMatchers(css,js,index。html,img,fonts,favicon。ico,verifyCode);}
  第二种方式是在configure(HttpSecurityhttp)方法中进行配置:Overrideprotectedvoidconfigure(HttpSecurityhttpSecurity)throwsException{httpSecurity。authorizeRequests()。antMatchers(hello)。permitAll()。anyRequest()。authenticated()}
  两种方式最大的区别在于,第一种方式是不走SpringSecurity过滤器链,而第二种方式是走SpringSecurity过滤器链,在过滤器链中,被请求放行。
  在我们使用SpringSecurity的时候,有的资源可以使用第一种方式额外放行,不需要验证,例如前端页面的静态资源,就可以按照第一种方式配置放行。
  有的资源放行,则必须使用第二种方式,例如登录接口。大家知道,登录接口也是必须要暴露出来的,不需要登录就能访问到的,但是我们却不能将登录接口用第一种方式暴露出来,登录请求必须要走SpringSecurity过滤器链,因为在这个过程中,还有其他事情要做,具体的登录流程想了解的可以自行百度。了解完了security的两种放行策略后,我们开始实现
  首先创建一个自定义注解Target({ElementType。METHOD})注解放置的目标位置,METHOD是可注解在方法级别上Retention(RetentionPolicy。RUNTIME)注解在哪个阶段执行Documented生成文档publicinterfaceIgnoreAuth{}
  这里说明一下,Target({ElementType。METHOD})我的实现方式,注解只能标记在带有RequestMapping注解的方法上。具体为什么下面的实现方式看完就懂了。
  接下来创建一个security的配置类SecurityConfig并继承WebSecurityConfigurerAdapterEnableGlobalMethodSecurity(prePostEnabledtrue,securedEnabledtrue)publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{AutowiredprivateRequestMappingHandlerMappingrequestMappingHandlerMapping;description:使用这种方式放行的接口,不走SpringSecurity过滤器链,无法通过SecurityContextHolder获取到登录用户信息的,因为它一开始没经过SecurityContextPersistenceFilter过滤器链。dateTime:202171910:22Overridepublicvoidconfigure(WebSecurityweb)throwsException{WebSecurityandweb。ignoring()。and();MapRequestMappingInfo,HandlerMethodhandlerMethodsrequestMappingHandlerMapping。getHandlerMethods();handlerMethods。forEach((info,method){带IgnoreAuth注解的方法直接放行if(StringUtils。isNotNull(method。getMethodAnnotation(IgnoreAuth。class))){根据请求类型做不同的处理info。getMethodsCondition()。getMethods()。forEach(requestMethod{switch(requestMethod){caseGET:getPatternsCondition得到请求url数组,遍历处理info。getPatternsCondition()。getPatterns()。forEach(pattern{放行and。ignoring()。antMatchers(HttpMethod。GET,pattern);});break;casePOST:info。getPatternsCondition()。getPatterns()。forEach(pattern{and。ignoring()。antMatchers(HttpMethod。POST,pattern);});break;caseDELETE:info。getPatternsCondition()。getPatterns()。forEach(pattern{and。ignoring()。antMatchers(HttpMethod。DELETE,pattern);});break;casePUT:info。getPatternsCondition()。getPatterns()。forEach(pattern{and。ignoring()。antMatchers(HttpMethod。PUT,pattern);});break;default:break;}});}});}}
  在这里使用Spring为我们提供的RequestMappingHandlerMapping类,我们可以通过requestMappingHandlerMapping。getHandlerMethods();获取到所有的RequestMappingInfo信息。
  以下是源码部分,可不看,看了可以加深理解
  这里简单说一下RequestMappingHandlerMapping的工作流程,便于理解。我们通过翻看源码
  继承关系如上图所示。
  AbstractHandlerMethodMapping实现了InitializingBean接口publicinterfaceInitializingBean{voidafterPropertiesSet()throwsException;}
  AbstractHandlerMethodMapping类中通过afterPropertiesSet方法调用initHandlerMethods进行初始化publicvoidafterPropertiesSet(){this。initHandlerMethods();}protectedvoidinitHandlerMethods(){String〔〕var1this。getCandidateBeanNames();intvar2var1。length;for(intvar30;var3var2;var3){StringbeanNamevar1〔var3〕;if(!beanName。startsWith(scopedTarget。)){this。processCandidateBean(beanName);}}this。handlerMethodsInitialized(this。getHandlerMethods());}
  再调用processCandidateBean方法:protectedvoidprocessCandidateBean(StringbeanName){ClassbeanTypenull;try{beanTypethis。obtainApplicationContext()。getType(beanName);}catch(Throwablevar4){if(this。logger。isTraceEnabled()){this。logger。trace(CouldnotresolvetypeforbeanbeanName,var4);}}if(beanType!nullthis。isHandler(beanType)){this。detectHandlerMethods(beanName);}}
  通过调用方法中的isHandler方法是不是requestHandler方法,可以看到源码是通过RequestMapping,Controller注解进行判断的。protectedbooleanisHandler(Classlt;?beanType){returnAnnotatedElementUtils。hasAnnotation(beanType,Controller。class)AnnotatedElementUtils。hasAnnotation(beanType,RequestMapping。class);}
  判断通过后,调用detectHandlerMethods方法将handler注册到HandlerMethod的缓存中。protectedvoiddetectHandlerMethods(Objecthandler){Classlt;?handlerTypehandlerinstanceofString?this。obtainApplicationContext()。getType((String)handler):handler。getClass();if(handlerType!null){Classlt;?userTypeClassUtils。getUserClass(handlerType);MapMethod,TmethodsMethodIntrospector。selectMethods(userType,(method){try{returnthis。getMappingForMethod(method,userType);}catch(Throwablevar4){thrownewIllegalStateException(Invalidmappingonhandlerclass〔userType。getName()〕:method,var4);}});if(this。logger。isTraceEnabled()){this。logger。trace(this。formatMappings(userType,methods));}methods。forEach((method,mapping){MethodinvocableMethodAopUtils。selectInvocableMethod(method,userType);this。registerHandlerMethod(handler,invocableMethod,mapping);});}}
  通过registerHandlerMethod方法将handler放到privatefinalMapT,HandlerMethodmappingLookupnewLinkedHashMap();map中。
  而requestMappingHandlerMapping。getHandlerMethods()方法就是获取所有的HandlerMapping。publicMapT,HandlerMethodgetHandlerMethods(){this。mappingRegistry。acquireReadLock();Mapvar1;try{var1Collections。unmodifiableMap(this。mappingRegistry。getMappings());}finally{this。mappingRegistry。releaseReadLock();}returnvar1;}
  最后就是对map进行遍历,判断是否带有IgnoreAuth。class注解,然后针对不同的请求方式进行放行。handlerMethods。forEach((info,method){带IgnoreAuth注解的方法直接放行if(StringUtils。isNotNull(method。getMethodAnnotation(IgnoreAuth。class))){根据请求类型做不同的处理info。getMethodsCondition()。getMethods()。forEach(requestMethod{switch(requestMethod){caseGET:getPatternsCondition得到请求url数组,遍历处理info。getPatternsCondition()。getPatterns()。forEach(pattern{放行and。ignoring()。antMatchers(HttpMethod。GET,pattern);});break;casePOST:info。getPatternsCondition()。getPatterns()。forEach(pattern{and。ignoring()。antMatchers(HttpMethod。POST,pattern);});break;caseDELETE:info。getPatternsCondition()。getPatterns()。forEach(pattern{and。ignoring()。antMatchers(HttpMethod。DELETE,pattern);});break;casePUT:info。getPatternsCondition()。getPatterns()。forEach(pattern{and。ignoring()。antMatchers(HttpMethod。PUT,pattern);});break;default:break;}});}});
  看到这里就能理解我最开始的强调的需标记在带有RequestMapping注解的方法上。我这里使用到的是configure(WebSecurityweb)的放行方式。它是不走security的过滤链,是无法通过SecurityContextHolder获取到登录用户信息的,这点问题是需要注意的。

所以我说那个骰子呢?龙与地下城盗贼荣耀海报及幕后花絮在Netflix人气影集《怪奇物语》中,所有角色对于经典桌游《龙与地下城》都非常热衷,包含艾迪曼森、麦克、达斯汀、卢卡斯等人。而在《宅男行不行》裡,谢尔顿与室友们也曾玩过这款游……2022。12。04早安心语,正能量激励人的好句子美丽的早上早上好,今天是2022年12月04日,星期日,农历冬月(十一月)十一,壬寅年【虎年】辛亥月辛卯日国家宪法日。每天醒来告诉自己,微笑才会美,奔跑才会有力量,努力才会成功,记……发力直播电商经济珠海能否弯道超车珠海金稻电器有限公司的女主播在推销产品。南方日报记者关铭荣摄珠海南屏科技园。南方日报记者关铭荣摄双十二购物旺季即将到来,位于南屏科技园的珠海金稻电器有限公司格外热闹……冠心病的辨证论治以胀和痛分病在气在血或气血皆病冠心病的辨证论治以胀和痛分气、血。凡胸部憋胀为主者,病在气分,多为胸阳痹阻;凡疼痛明显者,病在血分,多为血瘀刺痛。若既有胸憋又有刺痛,为气血皆病。用药经验分享:……添男丁后不要忘了摸蛋蛋!及时发现治疗隐睾(声明:本文仅用于科普用途,为了保护患者隐私,以下内容里的相关信息已进行处理)记得那天正好是我上门诊,我刚到办公室打开电脑,准备叫外面排队的患者进来就诊,这时一位青年女性……10亿中债增担保票据解近渴,新城控股难言高枕无忧近期,新城控股成功发行由中债增提供担保的10亿元票据。能够获中债增的担保,或许说明,新城控股正在意义上跻身优质民营房企的行列之内。而这笔钱,对于新城控股而言格外重要……对今年境内外利率环境变化的六点认识文丨张涛、路思远(中国建设银行金融市场部,文章仅代表作者观点)今年以来,境内外的利率环境发生了巨大变化,外紧内松的环境特征得到持续强化,而伴随美联储和欧洲央行9月份议息会……法甲巴黎圣曼VS马赛,马赛球迷被禁止入场西甲皇马VS巴塞罗那(情报)本场裁判搭档曾执法巴萨德比大胜本场的主裁判是桑切斯马丁内斯,他将第六次执法国家德比,而埃尔南德斯将执行VAR任务。两人上次以相同角……二十年游历分享之283亚洲62新加坡1缘起我是今日头条的赵先生,在头条持续更新我的游记《二十年游历分享》,介绍世界上主要景点。本篇文章共有3张照片(没有特殊声明的照片都是赵先生自己拍摄的),0个音频,0个视频。……从土气小妹到贵妇,她到底动了哪?甘比的变化真的惊艳到我了,没想到财富的加持能力竟然这么厉害。竟然能压艳过美神黎姿。那么除开服装搭配,发型妆容等外部原因,她原生脸到底哪不一样了?首先是鼻头变精……谁来也不好使啊!雷霆5人得分20ampampamp队史第二次直播吧1月4日讯NBA常规赛,雷霆主场150117大胜凯尔特人。此役,缺少了当家球星亚历山大的雷霆全民皆兵,多点开花,10名上场球员中有5人得分20,其中基迪15中10高……生活的主旋律,一直都是热爱今天下午的阳光特别好,虽然窗外的风吹得树叶摇摇欲坠,但是架不住我想出门的小心思蠢蠢欲动。然而,几番纠结几番斗争之后还是把自己给劝住了。最后,退而求其次,茸姑娘帮我把卧室从一楼的……
蛋仔派对何须怨杨柳通关攻略蛋仔派对何须怨杨柳怎么过?何须怨杨柳是乐园工坊里的人气地图,小编带来蛋仔派对何须怨杨柳通关攻略,一起来看看吧。蛋仔派对何须怨杨柳通关攻略1、地图全景文艺的地图名暗戳……年轻人为何不换手机?因用4年的iPhone不输当下安卓手机近日00后年轻人4年不换手机受到热议,柏铭科技猜测这当中有不少年轻人用的手机是iPhone,因为iPhone非常受年轻人欢迎,而iPhone的性能足以使用4年以上也不输安卓中高……本赛季自命不凡的八大球星,欧文恃才傲物,利拉德江郎才尽九牛一毫莫自夸,骄傲自满必翻车。这句几句哲理的谚语同样适用于NBA舞台。在群星璀璨的舞台上,从来不缺少传奇亦或者天赋爆满的天选之子。但,有些超级球星,仰仗异于常人的天赋亦……预言成真!伊藤美诚不仅对国乒威胁降低,就连队内赛前四都没进8月14日,事关奥运资格积分争夺的日本T联赛个人赛决出了冠军,张本智和与早田希娜笑到最后,大魔王伊藤美诚呢?止步八强。之前,伊藤美诚疑似瞧不上T联赛,认为水平不高,自从2……冯远征的消失,是娱乐圈的悲哀01、消失的冯远征冯远征说:演员需要什么,演员需要靠角色说话,一个好的表现是一个完整的,带有塑造人物的表演。冯远征说这段话时底气十足,没有一丝的犹豫。因……双芯80W闪充vivoX80Pro登场,vivoX70加速沦vivoX80Pro还带来了双芯80W闪充、50W无线闪充、2E5超灵敏自由屏、大体积X轴直线电机、IP68防水防尘等升级。从而真正实现全面无短板。值得一提的是,由于vi……科技无国界?看看苹果手机是怎么做的俄乌冲突以来,在美国经济的制裁下,苹果公司直接关闭了俄罗斯境内的所有苹果手机部分功能,一时间导致了俄罗斯人民日常生活带来极大的阻碍。根据测试:在搭载iOS13。2。3的i……男人到中年要有格调,戴这3种首饰显得太油腻,长得帅也没用男人想要打扮得精致有格调,在整体造型中就不能忽略了首饰的重要性,首饰在造型中虽然占比面积小,但是对于完整程度和穿衣品味,都有着最显著的影响力。一款符合风格走向、提升造型亮点、突……诺基亚经典手机于2022年回归,支持4GLTE和microS诺基亚手机的新家HMDGlobal刚刚宣布了四款新设备,其中大部分都受到一些经典诺基亚型号的启发,包括平板电脑。诺基亚一直在推出其一些标志性设备的现代版本,最受欢迎的是诺基亚3……那一碗刀削面,暖了我的心2000年,母亲要去北京出差,带上了我,开启了我的第二趟北京之旅。在那趟旅程中,让我印象最深刻的,是那一碗刀削面,暖了我的心。那天傍晚,我和母亲正要回旅店,路上看到了一个……中国男篮新队长正式确定,不是郭艾伦,杜锋决定令球迷出乎意料中国男篮刚刚结束了在澳大利亚进行的世预赛第一阶段的比赛,两负东道主的表现并不能让人满意,并且主教练杜锋在用人方面也是遭到了很多球迷的质疑。接下来,中国男篮将马不停蹄地奔赴印尼,……续航1000km,10分钟充满80,麒麟电池成压倒燃油车最后近日,宁德时代发布了最新的CTP3。0麒麟电池,一系列的颠覆式数据狂吸眼球,比如突破1000的续航里程、系统能量密度高达255whkg,体积利用率高达72,10分钟充满80,账……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网