




下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
Shiro使用簡介核心組件SubjectSecurityManagerRealms核心組件Subject:即“當前操作用戶”SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通過SecurityManager來管理內部組件實例,并通過它來提供安全管理的各種服務Realm充當了Shiro與應用安全數據間的“橋梁”或者“連接器”。也就是說,當對用戶執行認證(登錄)和授權(訪問控制)驗證時,Shiro會從應用配置的Realm中查找用戶及其權限信息Shiro完整架構圖
其他主要組件Authenticator:認證,核實用戶身份Authorizer:授權,訪問控制SessionManager:CacheManager:對Shiro的其他組件提供緩存支持Shiro認證過程
Shiro認證過程1、應用程序構建了一個終端用戶認證信息的AuthenticationToken實例后,調用Subject.login方法。
2、Sbuject的實例通常是DelegatingSubject類(或子類)的實例對象,在認證開始時,會委托應用程序設置的securityManager實例調用securityManager.login(token)方法。
3、SecurityManager接受到token(令牌)信息后會委托內置的Authenticator的實例(通常都是ModularRealmAuthenticator類的實例)調用authenticator.authenticate(token).ModularRealmAuthenticator在認證過程中會對設置的一個或多個Realm實例進行適配,它實際上為Shiro提供了一個可拔插的認證機制。
Shiro認證過程4、如果在應用程序中配置了多個Realm,ModularRealmAuthenticator會根據配置的AuthenticationStrategy(認證策略)來進行多Realm的認證過程。在Realm被調用后,AuthenticationStrategy將對每一個Realm的結果作出響應。
注:如果應用程序中僅配置了一個Realm,Realm將被直接調用而無需再配置認證策略。
5、判斷每一個Realm是否支持提交的token,如果支持,Realm將調用getAuthenticationInfo(token);getAuthenticationInfo方法就是實際認證處理,我們通過覆蓋Realm的doGetAuthenticationInfo方法來編寫我們自定義的認證處理。認證代碼Subjectmyadmin=SecurityUtils.getSubject();if(!myadmin.isAuthenticated()){ UsernamePasswordTokentoken=new UsernamePasswordToken(account,password); token.setRememberMe(true);try{ myadmin.login(token);}catch(UnknownAccountExceptionuae){ message="用戶名不正確";return
ERROR;}認證代碼catch(IncorrectCredentialsExceptionice){ message="密碼錯誤"; return
ERROR;}catch(LockedAccountExceptionlae){ message="用戶被鎖"; return
ERROR;}catch(ExcessiveAttemptsExceptioneae){ message="用戶名或密碼錯誤"; return
ERROR;}catch(AuthenticationExceptionae){ message="用戶名或密碼錯誤"; return
ERROR;}}currentUser.logout();//退出代碼Shiro授權授權有著三個核心元素:權限、角色和用戶。權限Shiro權限聲明通常是使用以冒號分隔的表達式。下面以實例來說明權限表達式。
可查詢用戶數據
User:view
可查詢或編輯用戶數據
User:view,edit
可對用戶數據進行所有操作
User:*或User
可編輯id為123的用戶數據
User:edit:123
角色
Shiro支持兩種角色模式:
1、傳統角色:一個角色代表著一系列的操作,當需要對某一操作進行授權驗證時,只需判斷是否是該角色即可。這種角色權限相對簡單、模糊,不利于擴展。
2、權限角色:一個角色擁有一個權限的集合。授權驗證時,需要判斷當前角色是否擁有該權限。這種角色權限可以對該角色進行詳細的權限描述,適合更復雜的權限設計。
授權實現Shiro支持三種方式實現授權過程:1編碼實現2注解實現3JSPTaglig實現Shiro授權的內部處理機制
授權流程1、在應用程序中調用授權驗證方法(Subject的isPermitted*或hasRole*等)
2、Sbuject的實例通常是DelegatingSubject類(或子類)的實例對象,在認證開始時,會委托應用程序設置的securityManager實例調用相應的isPermitted*或hasRole*方法。
3、接下來SecurityManager會委托內置的Authorizer的實例(默認是ModularRealmAuthorizer類的實例,類似認證實例,它同樣支持一個或多個Realm實例認證)調用相應的授權方法。
4、每一個Realm將檢查是否實現了相同的Authorizer接口。然后,將調用Reaml自己的相應的授權驗證方法。
。
授權流程當使用多個Realm時,不同于認證策略處理方式,授權處理過程中:
1、當調用Realm出現異常時,將立即拋出異常,結束授權驗證。
2、只要有一個Realm驗證成功,那么將認為授權成功,立即返回,結束認證Shiro有3中認證策略的具體實現:
AtLeastOneSuccessfulStrategy只要有一個(或更多)的Realm驗證成功,那么認證將被視為成功FirstSuccessfulStrategy第一個Realm驗證成功,整體認證將被視為成功,且后續Realm將被忽略AllSuccessfulStrategy所有Realm成功,認證才視為成功基于傳統角色授權實現
SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.hasRole("administrator")){}else{}相關驗證方法1.hasRole(StringroleName)當用戶擁有指定角色時,返回true2.hasRoles(List<String>roleNames)按照列表順序返回相應的一個boolean值數組3.hasAllRoles(Collection<String>roleNames)如果用戶擁有所有指定角色時,返回true斷言支持
Shiro還支持以斷言的方式進行授權驗證。斷言成功,不返回任何值,程序繼續執行;斷言失敗時,將拋出異常信息。使用斷言,可以使我們的代碼更加簡潔。SubjectcurrentUser=SecurityUtils.getSubject();currentUser.checkRole("bankTeller");openBankAccount();斷言的相關方法Subject方法描述checkRole(StringroleName)斷言用戶是否擁有指定角色checkRoles(Collection<String>roleNames)斷言用戶是否擁有所有指定角色checkRoles(String...roleNames)對上一方法的方法重載基于權限角色授權實現
相比傳統角色模式,基于權限的角色模式耦合性要更低些,它不會因角色的改變而對源代碼進行修改,因此,基于權限的角色模式是更好的訪問控制方式。
它的代碼實現有以下幾種實現方式:基于權限對象的實現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?}相關方法1.isPermitted(Permissionp)Subject擁有制定權限時,返回treu2.isPermitted(List<Permission>perms)返回對應權限的boolean數組3.isPermittedAll(Collection<Permission>perms)Subject擁有所有制定權限時,返回true基于字符串的實現
SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted("printer:print:laserjet4400n")){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}斷言實現
SubjectcurrentUser=SecurityUtils.getSubject();Permissionp=newAccountPermission("open");currentUser.checkPermission(p);openBankAccount();SubjectcurrentUser=SecurityUtils.getSubject();currentUser.checkPermission("account:open");openBankAccount();斷言實現的相關方法1.checkPermission(Permissionp)斷言用戶是否擁有制定權限2.checkPermission(Stringperm)斷言用戶是否擁有制定權限3.checkPermissions(Collection<Permission>perms)斷言用戶是否擁有所有指定權限4.checkPermissions(String...perms)斷言用戶是否擁有所有指定權限基于注解的授權實現
@RequiresAuthentication
@RequiresGuest@RequiresPermissions("account:create")@RequiresRoles
@RequiresUser
基于JSPTAG的授權實現
<%@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實現在認證、授權內部實現機制中都有提到,最終處理都將交給Real進行處理。因為在Shiro中,最終是通過Realm來獲取應用程序中的用戶、角色及權限信息的。通常情況下,在Realm中會直接從我們的數據源中獲取Shiro需要的驗證信息。可以說,Realm是專用于安全框架的DAO.
認證實現
Shiro的認證過程最終會交由Realm執行,這時會調用Realm的getAuthenticationInfo(token)方法。
該方法主要執行以下操作:
1、檢查提交的進行認證的令牌信息
2、根據令牌信息從數據源(通常為數據庫)中獲取用戶信息
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;}}授權實現
而授權實現則與認證實現非常相似,在我們自定義的Realm中,重載doGetAuthorizationInfo()方法,重寫獲取用戶權限的方法即可。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的過濾器配置靜態用戶配置靜態角色配置其中,由于用戶、角色一般由后臺進行操作的動態數據,因此Shiro配置一般僅包含前兩項的配置。
ApacheShiro的大多數組件是基于POJO的,因此我們可以使用POJO兼容的任何配置機制進行配置,例如: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["系統常規管理,超級管理員"]/admins/product/indexRebuild**=authc,rolesAny["系統常規管理,超級管理員"]/admins/member/indexRebuild**=authc,rolesAny["系統常規管理,超級管理員"]</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()此目錄設置
2、URL可使用通配符,**代表任意子目錄
3、Shiro驗證URL時,URL匹配成功便不再繼續匹配查找。所以要注意配置文件中的URL順序,尤其在使用通配符時。
FilterChain定義說明
1、一個URL可以配置多個Filter,使用逗號分隔
2、當設置多個過濾器時,全部驗證通過,才視為通過
3、部分過濾器可指定參數,如perms,roles
Shiro內置的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內置過濾器詳解rest:例如/admins/user/**=authc,rest[user]根據請求的方法,想當與/admins/user/**=authc,perms[user:method]port:例如/admins/user/**=authc,prot[8081]當請求的rul端口不是8081時,跳轉到
perms:例如/admins/user/**=authc,perms[“user:add:*”]內置過濾器詳解prems參數可以寫多個,當寫多個時要加上雙引號,并且參數之間用逗號分割roles例如/admins/user/**=authc,roles[admin]參數可以寫多個,當寫多個時要加上雙引號,并且參數之間用逗號分割anon例如/admins/**=anon沒有參數,表示可以匿名使用內置過濾器詳解authc:例如/admins/user/**=authc
表示需要認證才能使用,沒有參數authcBasic:例如/admins/user/**=authcBasic沒有參數,表示httpBasic認證,沒有參數ssl:例如/admins/user/**=ssl沒有參數,表示安全url請求,httpsuser:例如/admins/user/**=user沒有參數,表示存在用戶,當登入操作時不做檢查會話管理可在任何應用或架構層一致地使用SessionAPI.那些希望使用會話的應用開發者,不必被迫使用Servlet或EJB容器了。或者,如果正在使用這些容器,開發者現在也可以選擇使用在任何層統一一致的會話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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 試劑捐贈協議書范本
- 消費公司轉讓協議書
- 委托建房協議書范文
- 吸毒調解協議書模板
- 建行大額轉賬協議書
- 建行協商還款協議書
- 旅游代表免責協議書
- 盲人按摩入股協議書
- 物流晚到賠付協議書
- 企業參評參賽協議書
- TCUWA40055-2023排水管道工程自密實回填材料應用技術規程
- 高二【化學(魯科版)】微項目:模擬和表征有機化合物分子結構-教學設計
- 10kV線路跨越等級公路施工方案
- 未成年人監護狀況基本情況表、監護人監護能力等級評估表、評估報告
- 江蘇省無錫市錫山區天一實驗中學2022-2023學年七下期中數學試題(原卷版)
- 排班表管理制度
- 房屋團購方案
- 警察服裝采購投標方案(技術方案)
- 醫院保潔服務投標方案(技術方案)
- (高清版)DB54∕T 0305-2023 高原裝配式混凝土建筑技術標準
- 家裝系統門窗合同范本
評論
0/150
提交評論