套-第一天shiro學(xué)習(xí)使用方法_第1頁(yè)
套-第一天shiro學(xué)習(xí)使用方法_第2頁(yè)
套-第一天shiro學(xué)習(xí)使用方法_第3頁(yè)
套-第一天shiro學(xué)習(xí)使用方法_第4頁(yè)
套-第一天shiro學(xué)習(xí)使用方法_第5頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余47頁(yè)可下載查看

下載本文檔

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

文檔簡(jiǎn)介

Shiro使用簡(jiǎn)介核心組件SubjectSecurityManagerRealms核心組件Subject:即“當(dāng)前操作用戶”SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通過(guò)SecurityManager來(lái)管理內(nèi)部組件實(shí)例,并通過(guò)它來(lái)提供安全管理的各種服務(wù)Realm充當(dāng)了Shiro與應(yīng)用安全數(shù)據(jù)間的“橋梁”或者“連接器”。也就是說(shuō),當(dāng)對(duì)用戶執(zhí)行認(rèn)證(登錄)和授權(quán)(訪問(wèn)控制)驗(yàn)證時(shí),Shiro會(huì)從應(yīng)用配置的Realm中查找用戶及其權(quán)限信息Shiro完整架構(gòu)圖

其他主要組件Authenticator:認(rèn)證,核實(shí)用戶身份Authorizer:授權(quán),訪問(wèn)控制SessionManager:CacheManager:對(duì)Shiro的其他組件提供緩存支持Shiro認(rèn)證過(guò)程

Shiro認(rèn)證過(guò)程1、應(yīng)用程序構(gòu)建了一個(gè)終端用戶認(rèn)證信息的AuthenticationToken實(shí)例后,調(diào)用Subject.login方法。

2、Sbuject的實(shí)例通常是DelegatingSubject類(或子類)的實(shí)例對(duì)象,在認(rèn)證開(kāi)始時(shí),會(huì)委托應(yīng)用程序設(shè)置的securityManager實(shí)例調(diào)用securityManager.login(token)方法。

3、SecurityManager接受到token(令牌)信息后會(huì)委托內(nèi)置的Authenticator的實(shí)例(通常都是ModularRealmAuthenticator類的實(shí)例)調(diào)用authenticator.authenticate(token).ModularRealmAuthenticator在認(rèn)證過(guò)程中會(huì)對(duì)設(shè)置的一個(gè)或多個(gè)Realm實(shí)例進(jìn)行適配,它實(shí)際上為Shiro提供了一個(gè)可拔插的認(rèn)證機(jī)制。

Shiro認(rèn)證過(guò)程4、如果在應(yīng)用程序中配置了多個(gè)Realm,ModularRealmAuthenticator會(huì)根據(jù)配置的AuthenticationStrategy(認(rèn)證策略)來(lái)進(jìn)行多Realm的認(rèn)證過(guò)程。在Realm被調(diào)用后,AuthenticationStrategy將對(duì)每一個(gè)Realm的結(jié)果作出響應(yīng)。

注:如果應(yīng)用程序中僅配置了一個(gè)Realm,Realm將被直接調(diào)用而無(wú)需再配置認(rèn)證策略。

5、判斷每一個(gè)Realm是否支持提交的token,如果支持,Realm將調(diào)用getAuthenticationInfo(token);getAuthenticationInfo方法就是實(shí)際認(rèn)證處理,我們通過(guò)覆蓋Realm的doGetAuthenticationInfo方法來(lái)編寫我們自定義的認(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="密碼錯(cuò)誤"; return

ERROR;}catch(LockedAccountExceptionlae){ message="用戶被鎖"; return

ERROR;}catch(ExcessiveAttemptsExceptioneae){ message="用戶名或密碼錯(cuò)誤"; return

ERROR;}catch(AuthenticationExceptionae){ message="用戶名或密碼錯(cuò)誤"; return

ERROR;}}currentUser.logout();//退出代碼Shiro授權(quán)授權(quán)有著三個(gè)核心元素:權(quán)限、角色和用戶。權(quán)限Shiro權(quán)限聲明通常是使用以冒號(hào)分隔的表達(dá)式。下面以實(shí)例來(lái)說(shuō)明權(quán)限表達(dá)式。

可查詢用戶數(shù)據(jù)

User:view

可查詢或編輯用戶數(shù)據(jù)

User:view,edit

可對(duì)用戶數(shù)據(jù)進(jìn)行所有操作

User:*或User

可編輯id為123的用戶數(shù)據(jù)

User:edit:123

角色

Shiro支持兩種角色模式:

1、傳統(tǒng)角色:一個(gè)角色代表著一系列的操作,當(dāng)需要對(duì)某一操作進(jìn)行授權(quán)驗(yàn)證時(shí),只需判斷是否是該角色即可。這種角色權(quán)限相對(duì)簡(jiǎn)單、模糊,不利于擴(kuò)展。

2、權(quán)限角色:一個(gè)角色擁有一個(gè)權(quán)限的集合。授權(quán)驗(yàn)證時(shí),需要判斷當(dāng)前角色是否擁有該權(quán)限。這種角色權(quán)限可以對(duì)該角色進(jìn)行詳細(xì)的權(quán)限描述,適合更復(fù)雜的權(quán)限設(shè)計(jì)。

授權(quán)實(shí)現(xiàn)Shiro支持三種方式實(shí)現(xiàn)授權(quán)過(guò)程:1編碼實(shí)現(xiàn)2注解實(shí)現(xiàn)3JSPTaglig實(shí)現(xiàn)Shiro授權(quán)的內(nèi)部處理機(jī)制

授權(quán)流程1、在應(yīng)用程序中調(diào)用授權(quán)驗(yàn)證方法(Subject的isPermitted*或hasRole*等)

2、Sbuject的實(shí)例通常是DelegatingSubject類(或子類)的實(shí)例對(duì)象,在認(rèn)證開(kāi)始時(shí),會(huì)委托應(yīng)用程序設(shè)置的securityManager實(shí)例調(diào)用相應(yīng)的isPermitted*或hasRole*方法。

3、接下來(lái)SecurityManager會(huì)委托內(nèi)置的Authorizer的實(shí)例(默認(rèn)是ModularRealmAuthorizer類的實(shí)例,類似認(rèn)證實(shí)例,它同樣支持一個(gè)或多個(gè)Realm實(shí)例認(rèn)證)調(diào)用相應(yīng)的授權(quán)方法。

4、每一個(gè)Realm將檢查是否實(shí)現(xiàn)了相同的Authorizer接口。然后,將調(diào)用Reaml自己的相應(yīng)的授權(quán)驗(yàn)證方法。

。

授權(quán)流程當(dāng)使用多個(gè)Realm時(shí),不同于認(rèn)證策略處理方式,授權(quán)處理過(guò)程中:

1、當(dāng)調(diào)用Realm出現(xiàn)異常時(shí),將立即拋出異常,結(jié)束授權(quán)驗(yàn)證。

2、只要有一個(gè)Realm驗(yàn)證成功,那么將認(rèn)為授權(quán)成功,立即返回,結(jié)束認(rèn)證Shiro有3中認(rèn)證策略的具體實(shí)現(xiàn):

AtLeastOneSuccessfulStrategy只要有一個(gè)(或更多)的Realm驗(yàn)證成功,那么認(rèn)證將被視為成功FirstSuccessfulStrategy第一個(gè)Realm驗(yàn)證成功,整體認(rèn)證將被視為成功,且后續(xù)Realm將被忽略AllSuccessfulStrategy所有Realm成功,認(rèn)證才視為成功基于傳統(tǒng)角色授權(quán)實(shí)現(xiàn)

SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.hasRole("administrator")){}else{}相關(guān)驗(yàn)證方法1.hasRole(StringroleName)當(dāng)用戶擁有指定角色時(shí),返回true2.hasRoles(List<String>roleNames)按照列表順序返回相應(yīng)的一個(gè)boolean值數(shù)組3.hasAllRoles(Collection<String>roleNames)如果用戶擁有所有指定角色時(shí),返回true斷言支持

Shiro還支持以斷言的方式進(jìn)行授權(quán)驗(yàn)證。斷言成功,不返回任何值,程序繼續(xù)執(zhí)行;斷言失敗時(shí),將拋出異常信息。使用斷言,可以使我們的代碼更加簡(jiǎn)潔。SubjectcurrentUser=SecurityUtils.getSubject();currentUser.checkRole("bankTeller");openBankAccount();斷言的相關(guān)方法Subject方法描述checkRole(StringroleName)斷言用戶是否擁有指定角色checkRoles(Collection<String>roleNames)斷言用戶是否擁有所有指定角色checkRoles(String...roleNames)對(duì)上一方法的方法重載基于權(quán)限角色授權(quán)實(shí)現(xiàn)

相比傳統(tǒng)角色模式,基于權(quán)限的角色模式耦合性要更低些,它不會(huì)因角色的改變而對(duì)源代碼進(jìn)行修改,因此,基于權(quán)限的角色模式是更好的訪問(wèn)控制方式。

它的代碼實(shí)現(xiàn)有以下幾種實(shí)現(xiàn)方式:基于權(quán)限對(duì)象的實(shí)現(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)限時(shí),返回treu2.isPermitted(List<Permission>perms)返回對(duì)應(yīng)權(quán)限的boolean數(shù)組3.isPermittedAll(Collection<Permission>perms)Subject擁有所有制定權(quán)限時(shí),返回true基于字符串的實(shí)現(xiàn)

SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted("printer:print:laserjet4400n")){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}斷言實(shí)現(xiàn)

SubjectcurrentUser=SecurityUtils.getSubject();Permissionp=newAccountPermission("open");currentUser.checkPermission(p);openBankAccount();SubjectcurrentUser=SecurityUtils.getSubject();currentUser.checkPermission("account:open");openBankAccount();斷言實(shí)現(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)實(shí)現(xiàn)

@RequiresAuthentication

@RequiresGuest@RequiresPermissions("account:create")@RequiresRoles

@RequiresUser

基于JSPTAG的授權(quán)實(shí)現(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實(shí)現(xiàn)在認(rèn)證、授權(quán)內(nèi)部實(shí)現(xiàn)機(jī)制中都有提到,最終處理都將交給Real進(jìn)行處理。因?yàn)樵赟hiro中,最終是通過(guò)Realm來(lái)獲取應(yīng)用程序中的用戶、角色及權(quán)限信息的。通常情況下,在Realm中會(huì)直接從我們的數(shù)據(jù)源中獲取Shiro需要的驗(yàn)證信息??梢哉f(shuō),Realm是專用于安全框架的DAO.

認(rèn)證實(shí)現(xiàn)

Shiro的認(rèn)證過(guò)程最終會(huì)交由Realm執(zhí)行,這時(shí)會(huì)調(diào)用Realm的getAuthenticationInfo(token)方法。

該方法主要執(zhí)行以下操作:

1、檢查提交的進(jìn)行認(rèn)證的令牌信息

2、根據(jù)令牌信息從數(shù)據(jù)源(通常為數(shù)據(jù)庫(kù))中獲取用戶信息

3、對(duì)用戶信息進(jìn)行匹配驗(yàn)證。

4、驗(yàn)證通過(guò)將返回一個(gè)封裝了用戶信息的AuthenticationInfo實(shí)例。

5、驗(yàn)證失敗則拋出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)實(shí)現(xiàn)

而授權(quán)實(shí)現(xiàn)則與認(rèn)證實(shí)現(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的配置主要分為四部分:

對(duì)象和屬性的定義與配置URL的過(guò)濾器配置靜態(tài)用戶配置靜態(tài)角色配置其中,由于用戶、角色一般由后臺(tái)進(jìn)行操作的動(dòng)態(tài)數(shù)據(jù),因此Shiro配置一般僅包含前兩項(xiàng)的配置。

ApacheShiro的大多數(shù)組件是基于POJO的,因此我們可以使用POJO兼容的任何配置機(jī)制進(jìn)行配置,例如:Java代碼、SpingXML、YAML、JSON、ini文件等等。基于spring的配置<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ī)管理,超級(jí)管理員"]/admins/product/indexRebuild**=authc,rolesAny["系統(tǒng)常規(guī)管理,超級(jí)管理員"]/admins/member/indexRebuild**=authc,rolesAny["系統(tǒng)常規(guī)管理,超級(jí)管理員"]</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[超級(jí)管理員]/admins/news/**=authc,roles[資訊管理],roles[超級(jí)管理員]/admins/survey/**=authc,rolesAny["資訊管理,超級(jí)管理員"]/admins/survey/**.jsp=authc,roles[資訊管理],roles[超級(jí)管理員]/admins/**=authcURL過(guò)濾器配置說(shuō)明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表達(dá)式說(shuō)明

1、URL目錄是基于HttpServletRequest.getContextPath()此目錄設(shè)置

2、URL可使用通配符,**代表任意子目錄

3、Shiro驗(yàn)證URL時(shí),URL匹配成功便不再繼續(xù)匹配查找。所以要注意配置文件中的URL順序,尤其在使用通配符時(shí)。

FilterChain定義說(shuō)明

1、一個(gè)URL可以配置多個(gè)Filter,使用逗號(hào)分隔

2、當(dāng)設(shè)置多個(gè)過(guò)濾器時(shí),全部驗(yàn)證通過(guò),才視為通過(guò)

3、部分過(guò)濾器可指定參數(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)置過(guò)濾器詳解rest:例如/admins/user/**=authc,rest[user]根據(jù)請(qǐng)求的方法,想當(dāng)與/admins/user/**=authc,perms[user:method]port:例如/admins/user/**=authc,prot[8081]當(dāng)請(qǐng)求的rul端口不是8081時(shí),跳轉(zhuǎn)到

perms:例如/admins/user/**=authc,perms[“user:add:*”]內(nèi)置過(guò)濾器詳解prems參數(shù)可以寫多個(gè),當(dāng)寫多個(gè)時(shí)要加上雙引號(hào),并且參數(shù)之間用逗號(hào)分割roles例如/admins/user/**=authc,roles[admin]參數(shù)可以寫多個(gè),當(dāng)寫多個(gè)時(shí)要加上雙引號(hào),并且參數(shù)之間用逗號(hào)分割anon例如/admins/**=anon沒(méi)有參數(shù),表示可以匿名使用內(nèi)置過(guò)濾器詳解authc:例如/admins/user/**=authc

表示需要認(rèn)證才能使用,沒(méi)有參數(shù)authcBasic:例如/admins/user/**=authcBasic沒(méi)有參數(shù),表示httpBasic認(rèn)證,沒(méi)有參數(shù)ssl:例如/admins/user/**=ssl沒(méi)有參數(shù),表示安全url請(qǐng)求,httpsuser:例如/admins/user/**=user沒(méi)有參數(shù),表示存在用戶,當(dāng)?shù)侨氩僮鲿r(shí)不做檢查會(huì)話管理可在任何應(yīng)用或架構(gòu)層一致地使用SessionAPI.那些希望使用會(huì)話的應(yīng)用開(kāi)發(fā)者,不必被迫使用Servlet或EJB容器了?;蛘撸绻谑褂眠@些容器,開(kāi)發(fā)者現(xiàn)在也可以選擇使用在任何層統(tǒng)一一致的會(huì)話API,取代Servlet或EJB機(jī)制。

代碼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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論