亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                SpringBoot整合SpringSecurityOauth2實(shí)現(xiàn)鑒權(quán)-動(dòng)態(tài)權(quán)限

                SpringBoot整合SpringSecurityOauth2實(shí)現(xiàn)鑒權(quán)-動(dòng)態(tài)權(quán)限

                寫在前面

                思考:為什么需要鑒權(quán)呢?

                系統(tǒng)開發(fā)好上線后,API接口會(huì)暴露在互聯(lián)網(wǎng)上會(huì)存在一定的安全風(fēng)險(xiǎn),例如:爬蟲、惡意訪問等。因此,我們需要對(duì)非開放API接口進(jìn)行用戶鑒權(quán),鑒權(quán)通過之后再允許調(diào)用。

                準(zhǔn)備

                spring-boot:2.1.4.RELEASE

                spring-security-oauth2:2.3.3.RELEASE(如果要使用源碼,不要隨意改動(dòng)這個(gè)版本號(hào),因?yàn)?.4往上的寫法不一樣了)

                mysql:5.7

                效果展示

                這邊只用了postman做測(cè)試,暫時(shí)未使用前端頁面來對(duì)接,下個(gè)版本角色菜單權(quán)限分配的會(huì)有頁面的展示

                1、訪問開放接口 http://localhost:7000/open/hello

                2、不帶token訪問受保護(hù)接口 http://localhost:7000/admin/user/info

                3、登錄后獲取token,帶上token訪問,成功返回了當(dāng)前的登錄用戶信息

                實(shí)現(xiàn)

                oauth2一共有四種模式,這邊就不做講解了,網(wǎng)上搜一搜,千篇一律

                因?yàn)楝F(xiàn)在只考慮做單方應(yīng)用的,所以使用的是密碼模式。

                后面會(huì)出一篇SpringCloud+Oauth2的文章,網(wǎng)關(guān)鑒權(quán)

                講一下幾個(gè)點(diǎn)吧

                1、攔截器配置動(dòng)態(tài)權(quán)限

                新建一個(gè) MySecurityFilter類,繼承AbstractSecurityInterceptor,并實(shí)現(xiàn)Filter接口

                初始化,自定義訪問決策管理器

                @PostConstruct public void init(){ super.setAuthenticationManager(authenticationManager); super.setAccessDecisionManager(myAccessDecisionManager); }

                自定義 過濾器調(diào)用安全元數(shù)據(jù)源

                @Overridepublic SecurityMetadataSource obtainSecurityMetadataSource() { return this.mySecurityMetadataSource;}

                先來看一下自定義過濾器調(diào)用安全元數(shù)據(jù)源的核心代碼

                以下代碼是用來獲取到當(dāng)前請(qǐng)求進(jìn)來所需要的權(quán)限(角色)

                /** * 獲得當(dāng)前請(qǐng)求所需要的角色 * @param object * @return * @throws IllegalArgumentException */ @Override public Collection getAttributes(Object object) throws IllegalArgumentException { String requestUrl = ((FilterInvocation) object).getRequestUrl(); if (IS_CHANGE_SECURITY) { loadResourceDefine(); } if (requestUrl.indexOf(“?”) > -1) { requestUrl = requestUrl.substring(0, requestUrl.indexOf(“?”)); } UrlPathMatcher matcher = new UrlPathMatcher(); List list = new ArrayList(); //無需權(quán)限的,直接返回 list.add(“/oauth/**”); list.add(“/open/**”); if(matcher.pathsMatchesUrl(list,requestUrl)) return null; Set roleNames = new HashSet(); for (Resc resc: resources) { String rescUrl = resc.getResc_url(); if (matcher.pathMatchesUrl(rescUrl, requestUrl)) { if(resc.getParent_resc_id() != null && resc.getParent_resc_id().intValue() == 1){ //默認(rèn)權(quán)限的則只要登錄了,無需權(quán)限匹配都可訪問 roleNames = new HashSet(); break; } Map map = new HashMap(); map.put(“resc_id”, resc.getResc_id()); // 獲取能訪問該資源的所有權(quán)限(角色) List roles = roleRescMapper.findAll(map); for (RoleRescDTO rr : roles) roleNames.add(rr.getRole_name()); } } Set configAttributes = new HashSet(); for(String roleName:roleNames) configAttributes.add(new SecurityConfig(roleName)); log.debug(“【所需的權(quán)限(角色)】:” + configAttributes); return configAttributes; }

                再來看一下自定義訪問決策管理器核心代碼,這段代碼主要是判斷當(dāng)前登錄用戶(當(dāng)前登錄用戶所擁有的角色會(huì)在最后一項(xiàng)寫到)是否擁有該權(quán)限角色

                @Override public void decide(Authentication authentication, Object o, Collection configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if(configAttributes == null){ //屬于白名單的,不需要權(quán)限 return; } Iterator iterator = configAttributes.iterator(); while (iterator.hasNext()){ ConfigAttribute configAttribute = iterator.next(); String needPermission = configAttribute.getAttribute(); for (GrantedAuthority ga: authentication.getAuthorities()) { if(needPermission.equals(ga.getAuthority())){ //有權(quán)限,可訪問 return; } } } throw new AccessDeniedException(“沒有權(quán)限訪問”); }

                2、自定義鑒權(quán)異常返回通用結(jié)果

                為什么需要這個(gè)呢,如果不配置這個(gè),對(duì)于前端,后端來說都很難去理解鑒權(quán)失敗返回的內(nèi)容,還不能統(tǒng)一解讀,廢話不多說,先看看不配置和配置了的返回情況

                (1)未自定義前,沒有攜帶token去訪問受保護(hù)的API接口時(shí),返回的結(jié)果是這樣的

                (2)我們規(guī)定一下,鑒權(quán)失敗的接口返回接口之后,變成下面這種了,是不是更利于我們處理和提示用戶

                好了,來看一下是在哪里去配置的吧

                我們資源服務(wù)器OautyResourceConfig,重寫下下面這部分的代碼,來自定義鑒權(quán)異常返回的結(jié)果

                大伙可以參考下這個(gè) https://blog.csdn.net/Pastxu/article/details/124538364

                @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.authenticationEntryPoint(authenticationEntryPoint) //token失效或沒攜帶token時(shí) .accessDeniedHandler(requestAccessDeniedHandler); //權(quán)限不足時(shí) }

                3、獲取當(dāng)前登錄用戶

                第一種:使用JWT攜帶用戶信息,拿到token后再解析

                暫不做解釋

                第二種:寫一個(gè)SecurityUser實(shí)現(xiàn)UserDetails接口(這個(gè)工程中使用的是這一種)

                原來的只有UserDetails接口只有username和password,這里我們加上我們系統(tǒng)中的User

                protected User user; public SecurityUser(User user) { this.user = user; } public User getUser() { return user; }

                在BaseController,每個(gè)Controller都會(huì)繼承這個(gè)的,在里面寫給getUser()的方法,只要用戶帶了token來訪問,我們可以直接獲取當(dāng)前登錄用戶的信息了

                protected User getUser() { try { SecurityUser userDetails = (SecurityUser) SecurityContextHolder.getContext().getAuthentication() .getPrincipal(); User user = userDetails.getUser(); log.debug(“【用戶:】:” + user); return user; } catch (Exception e) { } return null; }

                那么用戶登錄成功后,如何去拿到用戶的角色集合等呢,這里面就要實(shí)現(xiàn)UserDetailsService接口了

                @Servicepublic class TokenUserDetailsService implements UserDetailsService{ @Autowired private LoginService loginService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = loginService.loadUserByUsername(username); //這個(gè)我們拎出來處理 if(Objects.isNull(user)) throw new UsernameNotFoundException(“用戶名不存在”); return new SecurityUser(user); }}

                然后在我們的安全配置類中設(shè)置UserDetailsService為上面的我們自己寫的就行

                @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); }

                最后我們只需要在loginService里面實(shí)現(xiàn)我們的方法就好,根據(jù)我們的實(shí)際業(yè)務(wù)處理判斷該用戶是否存在等

                @Override public User loadUserByUsername(String username){ log.debug(username); Map map = new HashMap(); map.put(“username”,username); map.put(“is_deleted”,-1); User user = userMapper.findByUsername(map); if(user != null){ map = new HashMap(); map.put(“user_id”,user.getUser_id()); //查詢用戶的角色 List userRoles = userRoleMapper.findAll(map); user.setRoles(listRoles(userRoles)); //權(quán)限集合 Collection authorities = merge(userRoles); user.setAuthorities(authorities); return user; } return null; }

                大功告成啦,趕緊動(dòng)起手來吧!

                附上源碼地址:https://gitee.com/jae_1995/spring-boot-oauth2

                數(shù)據(jù)庫文件在這

                點(diǎn)個(gè)小贊唄

                鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年6月21日 15:14
                下一篇 2022年6月21日 15:14

                相關(guān)推薦

                • ios手游模擬器(手游模擬器ios)

                  本文主要講的是ios手游模擬器,以及和手游模擬器ios相關(guān)的知識(shí),如果覺得本文對(duì)您有所幫助,不要忘了將本文分享給朋友。 哪個(gè)iOS模擬器能多開手游賬號(hào)?可以推薦個(gè)好用的模擬器給我嗎…

                  2022年11月27日
                • 短視頻策劃內(nèi)容的3個(gè)要點(diǎn)(短視頻策劃內(nèi)容怎么做)

                  短視頻在制作時(shí),內(nèi)容框架非常重要。如果直奔主題,然后結(jié)束,聚卓告訴你,這樣的短視頻已經(jīng)過時(shí)了?,F(xiàn)在的短視頻需要框架的,但不是任何框架,它需要一種易于理解和消化的框架。而且,現(xiàn)在大多…

                  2022年11月27日
                • 美團(tuán)第三季度實(shí)現(xiàn)營收626億元,即時(shí)配送訂單量增至50億筆

                  新京報(bào)訊(記者秦勝南)11月25日,美團(tuán)發(fā)布業(yè)績公告顯示,第三季度營收為626億元,較去年同比增長28.2%,凈利潤為12.2億元。第三季度,美團(tuán)即時(shí)配送訂單數(shù)增長至50億筆。截至…

                  2022年11月27日
                • 卡梅隆透露萊昂納多因不想試鏡差點(diǎn)沒演《泰坦尼克號(hào)》

                  導(dǎo)演詹姆斯·卡梅隆在接受 GQ雜志采訪時(shí)回憶稱,萊昂納多·迪卡普里奧差點(diǎn)沒有在 1997 年《泰坦尼克號(hào)》中飾演杰克,僅因?yàn)樗⒉幌霝樵摻巧囩R。 卡梅隆回憶道:“我記得第一次萊昂…

                  2022年11月26日
                • 個(gè)人怎么做抖音帶貨(個(gè)人做抖音帶貨能賺錢嗎)

                  抖音如今是大家很熟悉的短視頻平臺(tái),不過現(xiàn)在的抖音卻不只是短視頻那么簡單,它的功能非常豐富,其中一個(gè)就是可以帶貨,相信很多小伙伴都有在抖音上買過東西,抖音如今的變現(xiàn)能力也是不容小覷的…

                  2022年11月25日
                • 非匿名指令卡池怎么選擇?非匿名指令新手卡池推薦

                  非匿名指令卡池怎么選擇?新手玩家在選擇卡池的時(shí)候通常就會(huì)很糾結(jié),在不知道要抽取哪個(gè)卡池的時(shí)候可以看看下面的攻略,小編會(huì)給大家?guī)砜ǔ爻槿〉慕ㄗh,不知道如何選擇的時(shí)候就來看看小編的推…

                  2022年11月25日
                • 非匿名指令PVE開荒角色怎么選?非匿名指令節(jié)奏榜一覽

                  非匿名指令PVE開荒角色怎么選?可供玩家選擇的角色有很多,想要找到強(qiáng)勢(shì)一些的角色,可以通過下面小編帶來的攻略了解最新的節(jié)奏榜,大家可以根據(jù)小編帶來的節(jié)奏榜去了解角色的強(qiáng)度,方便大家…

                  2022年11月25日
                • 專訪|蔡文靜:作品被觀眾看到是種幸福

                  “我愛葉芯,愛她的純粹,愛她的執(zhí)著,愛她心無旁騖,積極努力?!贝饲?,蔡文靜在社交媒體發(fā)表長文,寫下對(duì)電視劇《底線》中葉芯這一角色的喜愛與不舍。 而今,葉芯也即將和江蘇衛(wèi)視的觀眾道聲…

                  2022年11月25日
                • 小紅書平臺(tái)的一些機(jī)制及玩法詳解(小紅書玩法有哪些)

                  關(guān)于小紅書 一:小紅書平臺(tái)的一些機(jī)制 1. 筆記內(nèi)容的CES評(píng)分機(jī)制 2. 筆記流量入口與長尾效應(yīng) 二:小紅書優(yōu)質(zhì)筆記的特點(diǎn)(分維度、類型分析) 1.筆記的本身架構(gòu)組成 維度 2.…

                  2022年11月25日
                • 百度關(guān)鍵詞快速排名的4大原理解析(百度怎么刷關(guān)鍵詞)

                  近期百度公告驚雷算法2.0,升級(jí)之快還是第一次吧,看來百度對(duì)于刷點(diǎn)擊行為是零容忍了。之前尹華峰SEO技術(shù)博客介紹過一篇如何使用刷點(diǎn)擊工具,其實(shí)市面上有很多這類SEO快速排名的軟件,…

                  2022年11月25日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息