在項(xiàng)目中集成shiro權(quán)限框架_第1頁
在項(xiàng)目中集成shiro權(quán)限框架_第2頁
在項(xiàng)目中集成shiro權(quán)限框架_第3頁
在項(xiàng)目中集成shiro權(quán)限框架_第4頁
在項(xiàng)目中集成shiro權(quán)限框架_第5頁
已閱讀5頁,還剩36頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、在項(xiàng)目中集成shiro權(quán)限框架(1)Shiro是一個(gè)功能強(qiáng)大的輕量級(jí)權(quán)限框架,相對(duì)其它權(quán)限框架(比如springsecurity)來說,要易用得很,下面,我給大家講講如何在一個(gè)項(xiàng)目中簡單整合shiro。我們通常所說的權(quán)限,就是要判斷某個(gè)操作者是否有操作某個(gè)資源的權(quán)限,而資源,可以是菜單、鏈接、功能按鈕、業(yè)務(wù)方法、某類型的數(shù)據(jù)等等,根據(jù)需求,每個(gè)項(xiàng)目的權(quán)限可能都有所不同,通用萬能權(quán)限系統(tǒng)是不存在的。Shrio的權(quán)限包括認(rèn)證、授權(quán)、密碼管理、會(huì)話管理等四個(gè)部分,每一個(gè)部分,shrio都進(jìn)行了抽象,以做到和具體應(yīng)用平臺(tái)、環(huán)境的無關(guān)。關(guān)于shiro的基礎(chǔ)了解,大家可到這里去看看:權(quán)限系統(tǒng)的設(shè)計(jì),根據(jù)不

2、同的權(quán)限粒度,會(huì)用所不同,比如:有的系統(tǒng)到菜單級(jí),而有的到每一個(gè)功能按鈕級(jí),有的到方法級(jí),有的到業(yè)務(wù)數(shù)據(jù)級(jí),我在這僅僅討論前兩類。上面是一個(gè)對(duì)象關(guān)系圖,模塊在此處僅僅為菜單進(jìn)行邏輯歸類,當(dāng)然,也可以建立菜單和功能的一對(duì)多關(guān)系,為功能進(jìn)行邏輯歸類。當(dāng)然,菜單也可以建成關(guān)聯(lián)的樹狀結(jié)構(gòu),以更好擴(kuò)展。根據(jù)對(duì)象關(guān)系,可以設(shè)計(jì)出表結(jié)構(gòu),我直接貼出數(shù)據(jù)截圖:模塊表:菜單表:操作表,一般對(duì)應(yīng)頁面中的按鈕,其中f_action_flag對(duì)應(yīng)于restful中的增、刪、查、改:角色表:角色-菜單關(guān)系表:角色-功能表:用戶表:用戶-角色關(guān)系表:上面截圖中,真正有效的表7張,權(quán)限控制到頁面及功能上。下篇,貼出上面的類

3、代碼及class映射文件。在項(xiàng)目中集成shiro權(quán)限框架(2)基礎(chǔ)代碼貼上:對(duì)象如下:/*用戶對(duì)象*authorLjh*/publicclassUserimplementsSerializable/學(xué)生編碼(由系統(tǒng)自動(dòng)生成)privateLongid;/姓名NotEmpty(message=姓名不可以為空!)Length(min=2,max=5)privateStringname;/出生日期NotNull(message=生日不能為空)Past(message=生日輸入不正確,請(qǐng)核對(duì)!)privateDatebirthday;/登錄密碼privateStringpassword=111;/用戶

4、角色集合字符privateSetroles=newHashSet();/*得到該用戶可訪問的模塊,模塊中的菜單將實(shí)例化*return*/publicListgetModels()Listmodels=newArrayList();for(Iteratorits=this.getMenus().iterator();its.hasNext();)Menum=its.next();if(!models.contains(m.getModel()Modelmodel=newModel();model.setId(m.getModel().getId();model.setDisplayOrder(m

5、.getDisplayOrder();model.setModelName(m.getModel().getModelName();model.getMenus().add(m);models.add(model);elsefor(Modelmodel:models)if(model.getId()=m.getModel().getId()model.getMenus().add(m);break;Collections.sort(models);returnmodels;/*得到用戶可訪問的菜單資源*return*/publicSetgetMenus()Setmenus=newHashSet

6、();for(Iteratorrole=this.getRoles().iterator();role.hasNext();)menus.addAll(role.next().getMenus();returnmenus;/用戶菜操作功能權(quán)限集合字符串描述publicSetgetOperationPermissionsAsString()Setpomissions=newHashSet();Iteratorroles=this.getRoles().iterator();Operationop;MapString,HashSetp_map=newHashMapString,HashSet();

7、while(roles.hasNext()Iteratoroperations=roles.next().getOperations().iterator();while(operations.hasNext()op=operations.next();Stringkey=op.getUrl();if(!key.startsWith(/)key=/+key;if(p_map.get(key)=null)p_map.put(key,newHashSet();p_map.get(key).add(op.getActionFlag();/構(gòu)建形如:doc:read,moveuser:modify,u

8、sers:read,user:modify,read,create的權(quán)限字串for(EntryString,HashSetentry:p_map.entrySet()pomissions.add(entry.getKey()+:+entry.getValue().toString().replace(,).replace(,).replace(,);returnpomissions;/用戶菜單權(quán)限集合字符串描述/publicSetgetMenuPermissionsAsString()/Setpomissions=newHashSet();/Iteratorroles=this.getRole

9、s().iterator();/while(roles.hasNext()/Iteratormenus=roles.next().getMenus().iterator();/while(menus.hasNext()/pomissions.add(menus.next().getCode();/returnpomissions;/*得到我的全部權(quán)限*return*/publicSetgetPermissionsAsString()Setpermissions=newHashSet();/permissions.addAll(getMenuPermissionsAsString();permi

10、ssions.addAll(getOperationPermissionsAsString();returnpermissions;/得到用戶角色字符串描述publicSetgetRolesAsString()Setstr_roles=newHashSet();Iteratorroles=this.getRoles().iterator();while(roles.hasNext()str_roles.add(roles.next().getRoleCode();returnstr_roles;角色對(duì)象:publicclassRoleimplementsSerializable/OIDpriv

11、ateintid;/顯示名稱privateStringdisplayName;/角色編碼,用于生成權(quán)限框架的惟一標(biāo)識(shí)privateStringroleCode;/角色可以操作的菜單privateSetmenus=newHashSet();/角色可操作的操作功能【對(duì)應(yīng)于增、刪、查、改等功能】privateSetoperations=newHashSet();菜單對(duì)象:publicclassMenuimplementsResource,Comparable,Serializable/OIDprivateintid;privateStringcode;privateStringname;/顯示順序p

12、rivateintdisplayOrder;/url地址privateStringurl;/所屬模塊privateModelmodel;OverridepublicintcompareTo(Objectmenu)Menum=(Menu)menu;returnm.getDisplayOrder()-this.getDisplayOrder();操作功能對(duì)象:publicclassOperationimplementsResource,Serializable/OIDprivateintid;/操作碼(保留待用)privateStringcode;/名稱privateStringname;/操作標(biāo)

13、志read:讀取,create:新增,modify:修改,delete:刪除/在rest風(fēng)格中,將請(qǐng)求方式映射為上述四種操作,設(shè)計(jì)為字符串,以方便今后擴(kuò)展privateStringactionFlag;/操作url地址,比如:/user/*privateStringurl;/所屬菜單privateMenumenu;/顯示順序,保留待用privateintdisplayOrder;功能模塊對(duì)象:/*功能模塊*authorAdministrator*/publicclassModelimplementsComparable,Serializable/publicclassModelprivatei

14、ntid;privateStringmodelName;/顯示順序privateintdisplayOrder;privateSetmenus=newHashSet();資源抽象對(duì)象,目前暫未使用:/*資源抽象類*authorAdministrator*/publicinterfaceResource/得到資源編碼publicStringgetResCode();最后,貼上hbm文件?;A(chǔ)的代碼完成了,其實(shí),user中已經(jīng)有部分和權(quán)限驗(yàn)證相關(guān)的代碼了,后面我詳細(xì)講解。在項(xiàng)目中集成shiro權(quán)限框架(3)Shiro與spring已經(jīng)有完整的整合方法,所以,我們先在web.xml中添對(duì)過濾器,將需

15、要驗(yàn)證的請(qǐng)求,攔截到shiro中。shiroFilterorg.springframework.web.filter.DelegatingFilterProxytargetFilterLifecycletrueshiroFilter/*在spring配置中添加下面的支持bean.其中filterChainDefinitions部分,簡單的項(xiàng)目可以直接寫死,我們這里采用的是啟動(dòng)時(shí)讀取生成,如果寫死,將會(huì)出現(xiàn)類似下面的代碼:/js/*=anon/css/*=anon/login.jsp=anon/login=anon/docs/doc1.jsp=authc,roleOrFilteradmin,de

16、v/admin/manager.jsp=authc,roleOrFilteradmin/admin/user/*=authc,rest/admin/user/*/userinfo/myinfo.jsp=authc,roleOrFiltertest,dev,admin/*=authc這段靜態(tài)權(quán)限代碼中用到了過濾器,我得給大家說一下:anon部分是不需要進(jìn)行驗(yàn)證的,即這部分是要放行的(注意*與*是有區(qū)別的,*表示該目錄下的所有,當(dāng)然也包括子目錄下的東西,而*僅指當(dāng)前目錄下的東西)。Authc,這個(gè)是需要登錄的人才可以訪問的。roleOrFile,這個(gè)是我定義的,只要這個(gè)過濾器中的一個(gè)角色滿足,即可

17、訪問,而shiro提供的role過濾器,是當(dāng)所有角色都滿足時(shí)才可訪問。Rest是restful過濾器,會(huì)將get,post,put,delete轉(zhuǎn)換為對(duì)資源的read.create,modify,delete操作。當(dāng)然,shiro還提供了其它的過濾器,大家可以自己去看看,比如:permission過濾器,shiro對(duì)權(quán)限的描述采用wildcard字串,功能強(qiáng)大且可讀性強(qiáng)。另外一點(diǎn)要接出,shiro在里使用最先匹配規(guī)則,一旦匹配成功,將不再進(jìn)行后續(xù)的過濾規(guī)則檢查,因此,在書寫時(shí)一定要注意順序,比如,你把/*=anon寫到第一行,那么后面的一切都將不會(huì)再檢測(cè)。好了,下面來講如何動(dòng)態(tài)生成這個(gè)規(guī)則,大

18、家看我的配置中有value=#authService.loadFilterChainDefinitions(),這個(gè)是springel表達(dá)式語言,表示調(diào)用容器中的另一個(gè)bean的方法,把這個(gè)方法的返回結(jié)果,賦值給filterChainDefinitions屬性。在些再補(bǔ)充一些權(quán)限字串的知識(shí):shiro所支持的廣義權(quán)限字串表達(dá)式,共有三種:1、簡單方式比如:subject.isPermitted(editNews),表示判斷某操作者是否有【編輯新聞】的權(quán)限。2、細(xì)粒度方式比如:subject.isPermitted(News:create),表示判斷某操作者是否有【新建新聞】的權(quán)限。3、實(shí)例級(jí)訪

19、問方式比如:subject.isPermitted(News:edit:10),表示判斷某操作者是否有【編輯id號(hào)是10新聞】的權(quán)限。上面3種方式中,可以用*表示所有,例如:News:*為對(duì)所有新聞的操作,*:create對(duì)所有事務(wù)都可以新增。還可以用逗號(hào)表示或都,News:edit:10,11表示可對(duì)10,11號(hào)新聞進(jìn)行編輯。如果要寫頁面權(quán)限,可參照如下配置:/index.jsp=anon/admin/*=authc,rolesadmin/docs/*=authc,permsdocument:read/*=authc我定義了一個(gè)權(quán)限相關(guān)的接口,如下:/*權(quán)限管理相關(guān)方法*authorljh*

20、/publicinterfaceIAuthService/*加載過濾配置信息*return*/publicStringloadFilterChainDefinitions();/*重新構(gòu)建權(quán)限過濾器*一般在修改了用戶角色、用戶等信息時(shí),需要再次調(diào)用該方法*/publicvoidreCreateFilterChains();其中一個(gè)方法用于加載生成權(quán)限規(guī)則字串,另一個(gè),用于用戶在系統(tǒng)中更改了角色-菜單,角色-功能關(guān)系時(shí),動(dòng)態(tài)重新生效的方法,實(shí)現(xiàn)類如下:Service(value=authService)publicclassAuthServiceImplimplementsIAuthServic

21、eprivatestaticfinalLoggerlog=Logger.getLogger(AuthServiceImpl.class);/注意/r/n前不能有空格privatestaticfinalStringCRLF=rn;privatestaticfinalStringLAST_AUTH_STR=/*=authcrn;ResourceprivateShiroFilterFactoryBeanshiroFilterFactoryBean;ResourceprivateIBaseDaodao;OverridepublicStringloadFilterChainDefinitions()St

22、ringBuffersb=newStringBuffer();sb.append(getFixedAuthRule().append(getDynaAuthRule().append(getRestfulOperationAuthRule().append(LAST_AUTH_STR);returnsb.toString();/生成restful風(fēng)格功能權(quán)限規(guī)則privateStringgetRestfulOperationAuthRule()Listoperations=dao.queryEntitys(fromOperationo,newObject);SetrestfulUrls=new

23、HashSet();for(Operationop:operations)restfulUrls.add(op.getUrl();StringBuffersb=newStringBuffer();for(Iteratorurls=restfulUrls.iterator();urls.hasNext();)Stringurl=urls.next();if(!url.startsWith(/)url=/+url;sb.append(url).append(=).append(authc,rest).append(url).append().append(CRLF);returnsb.toStri

24、ng();/根據(jù)角色,得到動(dòng)態(tài)權(quán)限規(guī)則privateStringgetDynaAuthRule()StringBuffersb=newStringBuffer();MapString,Setrules=newHashMapString,Set();Listroles=dao.queryEntitys(fromRolerleftjoinfetchr.menus,newObject);for(Rolerole:roles)for(Iteratormenus=role.getMenus().iterator();menus.hasNext();)Stringurl=menus.next().getU

25、rl();if(!url.startsWith(/)url=/+url;if(!rules.containsKey(url)rules.put(url,newHashSet();rules.get(url).add(role.getRoleCode();for(Map.EntryString,Setentry:rules.entrySet()sb.append(entry.getKey().append(=).append(authc,roleOrFilter).append(entry.getValue().append(CRLF);returnsb.toString();/得到固定權(quán)限驗(yàn)證

26、規(guī)則串privateStringgetFixedAuthRule()StringBuffersb=newStringBuffer();ClassPathResourcecp=newClassPathResource(fixed_auth_perties);Propertiesproperties=newOrderedProperties();tryproperties.load(cp.getInputStream();catch(IOExceptione)log.error(loadfixed_auth_pertieserror!,e);thrownewRuntim

27、eException(loadfixed_auth_pertieserror!);for(Iteratorits=properties.keySet().iterator();its.hasNext();)Stringkey=(String)its.next();sb.append(key).append(=).append(properties.getProperty(key).trim().append(CRLF);returnsb.toString();Override/此方法加同步鎖publicsynchronizedvoidreCreateFilterChains()A

28、bstractShiroFiltershiroFilter=null;tryshiroFilter=(AbstractShiroFilter)shiroFilterFactoryBean.getObject();catch(Exceptione)log.error(getShiroFilterfromshiroFilterFactoryBeanerror!,e);thrownewRuntimeException(getShiroFilterfromshiroFilterFactoryBeanerror!);PathMatchingFilterChainResolverfilterChainRe

29、solver=(PathMatchingFilterChainResolver)shiroFilter.getFilterChainResolver();DefaultFilterChainManagermanager=(DefaultFilterChainManager)filterChainResolver.getFilterChainManager();/清空老的權(quán)限控制manager.getFilterChains().clear();shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();shiroFilterFactoryBean.setFilterChainDefinitions(loadFilterChai

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論