版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
Shiro使用簡介核心組件SubjectSecurityManagerRealms核心組件Subject:即“當(dāng)前操作用戶”SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通過SecurityManager來管理內(nèi)部組件實例,并通過它來提供安全管理的各種服務(wù)Realm充當(dāng)了Shiro與應(yīng)用安全數(shù)據(jù)間的“橋梁”或者“連接器”。也就是說,當(dāng)對用戶執(zhí)行認(rèn)證(登錄)和授權(quán)(訪問控制)驗證時,Shiro會從應(yīng)用配置的Realm中查找用戶及其權(quán)限信息Shiro完整架構(gòu)圖
其他主要組件Authenticator:認(rèn)證,核實用戶身份Authorizer:授權(quán),訪問控制SessionManager:CacheManager:對Shiro的其他組件提供緩存支持Shiro認(rèn)證過程
Shiro認(rèn)證過程1、應(yīng)用程序構(gòu)建了一個終端用戶認(rèn)證信息的AuthenticationToken實例后,調(diào)用Subject.login方法。
2、Sbuject的實例通常是DelegatingSubject類(或子類)的實例對象,在認(rèn)證開始時,會委托應(yīng)用程序設(shè)置的securityManager實例調(diào)用securityManager.login(token)方法。
3、SecurityManager接受到token(令牌)信息后會委托內(nèi)置的Authenticator的實例(通常都是ModularRealmAuthenticator類的實例)調(diào)用authenticator.authenticate(token).ModularRealmAuthenticator在認(rèn)證過程中會對設(shè)置的一個或多個Realm實例進行適配,它實際上為Shiro提供了一個可拔插的認(rèn)證機制。
Shiro認(rèn)證過程4、如果在應(yīng)用程序中配置了多個Realm,ModularRealmAuthenticator會根據(jù)配置的AuthenticationStrategy(認(rèn)證策略)來進行多Realm的認(rèn)證過程。在Realm被調(diào)用后,AuthenticationStrategy將對每一個Realm的結(jié)果作出響應(yīng)。
注:如果應(yīng)用程序中僅配置了一個Realm,Realm將被直接調(diào)用而無需再配置認(rèn)證策略。
5、判斷每一個Realm是否支持提交的token,如果支持,Realm將調(diào)用getAuthenticationInfo(token);getAuthenticationInfo方法就是實際認(rèn)證處理,我們通過覆蓋Realm的doGetAuthenticationInfo方法來編寫我們自定義的認(rèn)證處理。認(rèn)證代碼Subjectmyadmin=SecurityUtils.getSubject();if(!myadmin.isAuthenticated()){ UsernamePasswordTokentoken=new UsernamePasswordToken(account,password); token.setRememberMe(true);try{ myadmin.login(token);}catch(UnknownAccountExceptionuae){ message="用戶名不正確";return
ERROR;}認(rèn)證代碼catch(IncorrectCredentialsExceptionice){ message="密碼錯誤"; return
ERROR;}catch(LockedAccountExceptionlae){ message="用戶被鎖"; return
ERROR;}catch(ExcessiveAttemptsExceptioneae){ message="用戶名或密碼錯誤"; return
ERROR;}catch(AuthenticationExceptionae){ message="用戶名或密碼錯誤"; return
ERROR;}}currentUser.logout();//退出代碼Shiro授權(quán)授權(quán)有著三個核心元素:權(quán)限、角色和用戶。權(quán)限Shiro權(quán)限聲明通常是使用以冒號分隔的表達式。下面以實例來說明權(quán)限表達式。
可查詢用戶數(shù)據(jù)
User:view
可查詢或編輯用戶數(shù)據(jù)
User:view,edit
可對用戶數(shù)據(jù)進行所有操作
User:*或User
可編輯id為123的用戶數(shù)據(jù)
User:edit:123
角色
Shiro支持兩種角色模式:
1、傳統(tǒng)角色:一個角色代表著一系列的操作,當(dāng)需要對某一操作進行授權(quán)驗證時,只需判斷是否是該角色即可。這種角色權(quán)限相對簡單、模糊,不利于擴展。
2、權(quán)限角色:一個角色擁有一個權(quán)限的集合。授權(quán)驗證時,需要判斷當(dāng)前角色是否擁有該權(quán)限。這種角色權(quán)限可以對該角色進行詳細(xì)的權(quán)限描述,適合更復(fù)雜的權(quán)限設(shè)計。
授權(quán)實現(xiàn)Shiro支持三種方式實現(xiàn)授權(quán)過程:1編碼實現(xiàn)2注解實現(xiàn)3JSPTaglig實現(xiàn)Shiro授權(quán)的內(nèi)部處理機制
授權(quán)流程1、在應(yīng)用程序中調(diào)用授權(quán)驗證方法(Subject的isPermitted*或hasRole*等)
2、Sbuject的實例通常是DelegatingSubject類(或子類)的實例對象,在認(rèn)證開始時,會委托應(yīng)用程序設(shè)置的securityManager實例調(diào)用相應(yīng)的isPermitted*或hasRole*方法。
3、接下來SecurityManager會委托內(nèi)置的Authorizer的實例(默認(rèn)是ModularRealmAuthorizer類的實例,類似認(rèn)證實例,它同樣支持一個或多個Realm實例認(rèn)證)調(diào)用相應(yīng)的授權(quán)方法。
4、每一個Realm將檢查是否實現(xiàn)了相同的Authorizer接口。然后,將調(diào)用Reaml自己的相應(yīng)的授權(quán)驗證方法。
。
授權(quán)流程當(dāng)使用多個Realm時,不同于認(rèn)證策略處理方式,授權(quán)處理過程中:
1、當(dāng)調(diào)用Realm出現(xiàn)異常時,將立即拋出異常,結(jié)束授權(quán)驗證。
2、只要有一個Realm驗證成功,那么將認(rèn)為授權(quán)成功,立即返回,結(jié)束認(rèn)證Shiro有3中認(rèn)證策略的具體實現(xiàn):
AtLeastOneSuccessfulStrategy只要有一個(或更多)的Realm驗證成功,那么認(rèn)證將被視為成功FirstSuccessfulStrategy第一個Realm驗證成功,整體認(rèn)證將被視為成功,且后續(xù)Realm將被忽略AllSuccessfulStrategy所有Realm成功,認(rèn)證才視為成功基于傳統(tǒng)角色授權(quán)實現(xiàn)
SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.hasRole("administrator")){}else{}相關(guān)驗證方法1.hasRole(StringroleName)當(dāng)用戶擁有指定角色時,返回true2.hasRoles(List<String>roleNames)按照列表順序返回相應(yīng)的一個boolean值數(shù)組3.hasAllRoles(Collection<String>roleNames)如果用戶擁有所有指定角色時,返回true斷言支持
Shiro還支持以斷言的方式進行授權(quán)驗證。斷言成功,不返回任何值,程序繼續(xù)執(zhí)行;斷言失敗時,將拋出異常信息。使用斷言,可以使我們的代碼更加簡潔。SubjectcurrentUser=SecurityUtils.getSubject();currentUser.checkRole("bankTeller");openBankAccount();斷言的相關(guān)方法Subject方法描述checkRole(StringroleName)斷言用戶是否擁有指定角色checkRoles(Collection<String>roleNames)斷言用戶是否擁有所有指定角色checkRoles(String...roleNames)對上一方法的方法重載基于權(quán)限角色授權(quán)實現(xiàn)
相比傳統(tǒng)角色模式,基于權(quán)限的角色模式耦合性要更低些,它不會因角色的改變而對源代碼進行修改,因此,基于權(quán)限的角色模式是更好的訪問控制方式。
它的代碼實現(xiàn)有以下幾種實現(xiàn)方式:基于權(quán)限對象的實現(xiàn)PermissionprintPermission=newPrinterPermission("laserjet4400n","print");SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted(printPermission)){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}PermissionprintPermission=newPrinterPermission("laserjet4400n","print");SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted(printPermission)){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}相關(guān)方法1.isPermitted(Permissionp)Subject擁有制定權(quán)限時,返回treu2.isPermitted(List<Permission>perms)返回對應(yīng)權(quán)限的boolean數(shù)組3.isPermittedAll(Collection<Permission>perms)Subject擁有所有制定權(quán)限時,返回true基于字符串的實現(xiàn)
SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted("printer:print:laserjet4400n")){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}斷言實現(xiàn)
SubjectcurrentUser=SecurityUtils.getSubject();Permissionp=newAccountPermission("open");currentUser.checkPermission(p);openBankAccount();SubjectcurrentUser=SecurityUtils.getSubject();currentUser.checkPermission("account:open");openBankAccount();斷言實現(xiàn)的相關(guān)方法1.checkPermission(Permissionp)斷言用戶是否擁有制定權(quán)限2.checkPermission(Stringperm)斷言用戶是否擁有制定權(quán)限3.checkPermissions(Collection<Permission>perms)斷言用戶是否擁有所有指定權(quán)限4.checkPermissions(String...perms)斷言用戶是否擁有所有指定權(quán)限基于注解的授權(quán)實現(xiàn)
@RequiresAuthentication
@RequiresGuest@RequiresPermissions("account:create")@RequiresRoles
@RequiresUser
基于JSPTAG的授權(quán)實現(xiàn)
<%@taglibprefix="shiro"uri=""%><shiro:guest></shiro:guest><shiro:authenticated></shiro:authenticated><shiro:notAuthenticated></shiro:notAuthenticated>Hello,<shiro:principal/>,howareyoutoday?<shiro:hasRolename="administrator"></shiro:hasRole><shiro:lacksRolename="administrator"></shiro:lacksRole><shiro:hasAnyRolesname="developer,projectmanager,administrator">.</shiro:lacksRole><shiro:hasPermissionname="user:create"></shiro:hasPermission><shiro:lacksPermissionname="user:create"></shiro:lacksPermission>Realm實現(xiàn)在認(rèn)證、授權(quán)內(nèi)部實現(xiàn)機制中都有提到,最終處理都將交給Real進行處理。因為在Shiro中,最終是通過Realm來獲取應(yīng)用程序中的用戶、角色及權(quán)限信息的。通常情況下,在Realm中會直接從我們的數(shù)據(jù)源中獲取Shiro需要的驗證信息。可以說,Realm是專用于安全框架的DAO.
認(rèn)證實現(xiàn)
Shiro的認(rèn)證過程最終會交由Realm執(zhí)行,這時會調(diào)用Realm的getAuthenticationInfo(token)方法。
該方法主要執(zhí)行以下操作:
1、檢查提交的進行認(rèn)證的令牌信息
2、根據(jù)令牌信息從數(shù)據(jù)源(通常為數(shù)據(jù)庫)中獲取用戶信息
3、對用戶信息進行匹配驗證。
4、驗證通過將返回一個封裝了用戶信息的AuthenticationInfo實例。
5、驗證失敗則拋出AuthenticationException異常信息。
Realm代碼@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthcToken)throwsAuthenticationException{UsernamePasswordTokentoken=(UsernamePasswordToken)authcToken;Adminuser=(Admin)adminDao.query().is("account",token.getUsername()).result();
if(user!=null){
return
newSimpleAuthenticationInfo(user.getAccount(),user.getPassword(),getName());}else{
return
null;}}授權(quán)實現(xiàn)
而授權(quán)實現(xiàn)則與認(rèn)證實現(xiàn)非常相似,在我們自定義的Realm中,重載doGetAuthorizationInfo()方法,重寫獲取用戶權(quán)限的方法即可。Realm代碼@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){Stringname=getName();Iteratoriterator=principals.fromRealm(name).iterator();StringuserName=null;if(iterator.hasNext()){userName=(String)iterator.next();}Adminuser=(Admin)adminDao.findOne("account",userName);if(user.getRoleSet()!=null){BuguMapper.fetchCascade(user,"roleSet");}
if(user!=null&&user.getRoleSet()!=null){SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo();
for(Rolegroup:user.getRoleSet()){
info.addRole(group.getName());
if(group.getPerssionSet()!=null){BuguMapper.fetchCascade(group,"perssionSet");
Iteratorit=group.getPerssionSet().iterator();
while(it.hasNext()){info.addStringPermission(((Permission)it.next()).getName());}}
}
returninfo;}else{
return
null;}Shiro配置ApacheShiro的配置主要分為四部分:
對象和屬性的定義與配置URL的過濾器配置靜態(tài)用戶配置靜態(tài)角色配置其中,由于用戶、角色一般由后臺進行操作的動態(tài)數(shù)據(jù),因此Shiro配置一般僅包含前兩項的配置。
ApacheShiro的大多數(shù)組件是基于POJO的,因此我們可以使用POJO兼容的任何配置機制進行配置,例如:Java代碼、SpingXML、YAML、JSON、ini文件等等?;趕pring的配置<beanid="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><propertyname="realm"ref="myRealm"/><propertyname="sessionMode"value="native"/><propertyname="sessionManager"ref="sessionManager"/></bean><beanid="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"><propertyname="sessionDAO"ref="sessionDAO"/></bean><beanid="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"></bean><beanid="myRealm"class="mons.utils.MongodbRealm"> <propertyname="adminDao"ref="adminDao"></property></bean><beanid="rolesAny"class="mons.context.RolesAnyAuthorizationFilter"></bean>基于spring的配置<beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><propertyname="securityManager"ref="securityManager"/><propertyname="loginUrl"value="/login/admin_login.jsp"/><propertyname="successUrl"value="/admins/"/><propertyname="unauthorizedUrl"value="/shows/error/no_permission.jsp"/><propertyname="filters"><util:map><entrykey="rolesAny"value-ref="rolesAny"/></util:map></property><propertyname="filterChainDefinitions"><value>/admins/news/indexRebuild**=authc,rolesAny["系統(tǒng)常規(guī)管理,超級管理員"]/admins/product/indexRebuild**=authc,rolesAny["系統(tǒng)常規(guī)管理,超級管理員"]/admins/member/indexRebuild**=authc,rolesAny["系統(tǒng)常規(guī)管理,超級管理員"]</value></property>
</bean>基于ini文件的配置[main]shiro.loginUrl=/login/admin_login.jspauthc.successUrl=/admins/roles.unauthorizedUrl=/shows/error/no_permission.jspperms.unauthorizedUrl=/shows/error/no_permission.jspinirealm=org.apache.shiro.realm.text.IniRealminirealm.resourcePath=classpath:shiro.inimons.utils.MongodbRealmadminDao=cn.eyes.core.admin.AdminDaomyrealm.adminDao=$adminDaosecurityManager.realms=$inirealm,$myrealmsessionManager=org.apache.shiro.web.session.mgt.DefaultWebSessionManagersecurityManager.sessionManager=$sessionManagermons.context.RolesAnyAuthorizationFiltersecurityManager.sessionManager.sessionListeners=$rolesAny[users]admin=1234567,*基于ini文件的配置[roles]admin=*[urls]/admins/news/indexRebuild**=authc,perms[indexrebuild:*]/admins/news/**.jsp=authc,roles[資訊管理],roles[超級管理員]/admins/news/**=authc,roles[資訊管理],roles[超級管理員]/admins/survey/**=authc,rolesAny["資訊管理,超級管理員"]/admins/survey/**.jsp=authc,roles[資訊管理],roles[超級管理員]/admins/**=authcURL過濾器配置說明URL_Ant_Path_Expression=Path_Specific_Filter_Chain[urls]
/index.html=anon
/user/create=anon
/user/**=authc
/admin/**=authc,roles[administrator]
/rest/**=authc,rest
/remoting/rpc/**=authc,perms["remote:invoke"]
URL表達式說明
1、URL目錄是基于HttpServletRequest.getContextPath()此目錄設(shè)置
2、URL可使用通配符,**代表任意子目錄
3、Shiro驗證URL時,URL匹配成功便不再繼續(xù)匹配查找。所以要注意配置文件中的URL順序,尤其在使用通配符時。
FilterChain定義說明
1、一個URL可以配置多個Filter,使用逗號分隔
2、當(dāng)設(shè)置多個過濾器時,全部驗證通過,才視為通過
3、部分過濾器可指定參數(shù),如perms,roles
Shiro內(nèi)置的FilterChain
anonorg.apache.shiro.web.filter.authc.AnonymousFilterauthcorg.apache.shiro.web.filter.authc.FormAuthenticationFilterauthcBasicorg.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilterpermsorg.apache.shiro.web.filter.authz.PermissionsAuthorizationFilterportorg.apache.shiro.web.filter.authz.PortFilterrestorg.apache.shiro.web.filter.authz.HttpMethodPermissionFilterrolesorg.apache.shiro.web.filter.authz.RolesAuthorizationFiltersslorg.apache.shiro.web.filter.authz.SslFilteruserorg.apache.shiro.web.filter.authc.UserFilter內(nèi)置過濾器詳解rest:例如/admins/user/**=authc,rest[user]根據(jù)請求的方法,想當(dāng)與/admins/user/**=authc,perms[user:method]port:例如/admins/user/**=authc,prot[8081]當(dāng)請求的rul端口不是8081時,跳轉(zhuǎn)到
perms:例如/admins/user/**=authc,perms[“user:add:*”]內(nèi)置過濾器詳解prems參數(shù)可以寫多個,當(dāng)寫多個時要加上雙引號,并且參數(shù)之間用逗號分割roles例如/admins/user/**=authc,roles[admin]參數(shù)可以寫多個,當(dāng)寫多個時要加上雙引號,并且參數(shù)之間用逗號分割anon例如/admins/**=anon沒有參數(shù),表示可以匿名使用內(nèi)置過濾器詳解authc:例如/admins/user/**=authc
表示需要認(rèn)證才能使用,沒有參數(shù)authcBasic:例如/admins/user/**=authcBasic沒有參數(shù),表示httpBasic認(rèn)證,沒有參數(shù)ssl:例如/admins/user/**=ssl沒有參數(shù),表示安全url請求,httpsuser:例如/admins/user/**=user沒有參數(shù),表示存在用戶,當(dāng)?shù)侨氩僮鲿r不做檢查會話管理可在任何應(yīng)用或架構(gòu)層一致地使用SessionAPI.那些希望使用會話的應(yīng)用開發(fā)者,不必被迫使用Servlet或EJB容器了?;蛘?,如果正在使用這些容器,開發(fā)者現(xiàn)在也可以選擇使用在任何層統(tǒng)一一致的會話API,取代Servlet或EJB機制。
代碼Sessionsession=subject.getSession();Sessionsession=subject.getSession(booleancreate);session.setAttribute("key",someValue);session.getAttribute(“key”)Datetimestamp=session.getLastAccessTime();session.setTimeout(millis);
加密<beanid="md5Matcher"class="org.apache.shiro.authc.credential.Md5CredentialsMatcher"></bean>
<beanid="myRealm"cl
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 北京體育職業(yè)學(xué)院《研究型建筑設(shè)計》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025版葵花籽品牌授權(quán)與營銷推廣合同3篇
- 膩子銷售合同
- 2025版數(shù)據(jù)中心機房消防設(shè)備隔音降噪施工合同
- 肌肉肥大訓(xùn)練課程設(shè)計
- 2025年幼兒園班班通互動教學(xué)解決方案合同3篇
- 設(shè)計合同簡易版
- 泰勒提出課程設(shè)計的
- 2025版餐飲行業(yè)代運營服務(wù)合同范本3篇
- 2025版酒店客房用品進出口采購合同3篇
- DB44-T 2480-2024 鋁及鋁合金深井鑄造安全技術(shù)規(guī)范
- 中醫(yī)適宜技術(shù)發(fā)展現(xiàn)狀
- 部編人教版四年級數(shù)學(xué)上冊期末考試卷(可打印)
- 一例阿爾茨海默病患者的護理查房
- 農(nóng)貿(mào)市場安全生產(chǎn)工作方案
- 咸陽租房合同
- 《鋼筋保護層檢測》課件
- YJ-T 27-2024 應(yīng)急指揮通信保障能力建設(shè)規(guī)范
- 合伙人協(xié)議書決策機制
- 西藏畜牧獸醫(yī)知識培訓(xùn)課件
- 護理專業(yè)人才培養(yǎng)方案論證報告
評論
0/150
提交評論