Simple? ? 簡單易用 Java Java Security 安全
Shiro是什么识颊?? ? ? ? 是Apache 下的一個強大易用的 Java安全框架耿焊,提供了認證授權揪惦,加密和會話管理等功能?????對比另一個安全框架Spring Sercurity,它更簡單和靈活搀别。
為什么要用Shiro丹擎?
Shiro常用的用途???????對于任何一個應用程序?Shiro 都可以提供全面的安全管理? ??
怎么使用Shiro歇父?
Apache Shiro特性
1蒂培,Authentication:身份認證/登錄,驗證用戶是不是擁有相應的身份榜苫;
2护戳,Authorization:授權,即驗證權限垂睬,驗證某個已認證的用戶是否擁有某個權限媳荒;即判斷用戶是否能做事情,常見的如:驗證某個用戶是否擁有某個角色驹饺∏恚或者細粒度的驗證某個用戶對某個資源是否具有某個權限。
3赏壹,Session Management:會話管理鱼炒,即用戶登錄后就是一次會話,在沒有退出之前蝌借,它的所有信息都在會話中昔瞧;會話可以是普通的JavaSE環(huán)境的,也可以是Web環(huán)境的菩佑。
4自晰,Cryptography:加密,保護數(shù)據(jù)的安全性稍坯,如密碼加密存儲到數(shù)據(jù)庫酬荞,而不是明文存儲;
5,Web Support:Web支持混巧,可以非常容易的集成到Web環(huán)境中
6糟把,Caching:緩存,比如用戶登錄后牲剃,其用戶信息,擁有的角色/權限不必每次去查雄可,提高效率凿傅。
7,Concurrency:Shiro支持多線程應用的并發(fā)驗證数苫,即如在一個線程中開啟另一個線程聪舒,能把權限自動傳播過去;
8虐急,Testing:提供測試支持
9箱残,Run As:允許一個用戶假裝為另一個用戶(如果他們允許)的身份進行訪問
10,Rember Me:記住我止吁,這是非常常見的功能被辑,即一次登錄后,下次再來的話不用登錄了敬惦。
Shiro不會去維護用戶盼理,維護權限;這些需要自己去設計/提供俄删;然后通過響應的接口注入給Shiro即可宏怔。
Shiro架構
對于一個好的框架,從外部看來應該具有非常簡單易于使用的API畴椰,且API契約明確臊诊;從內部來看的話,其應該有一個可擴展的架構斜脂,即非常容易插入用戶自定義實現(xiàn)抓艳,因為任何框架都不能滿足所有需求。
首先秽褒,從外部來看Shiro壶硅,即從應用程序的角度來觀察如何使用Shiro完成工作。如下圖:
可以看到:應用代碼直接交互的對象是Subject销斟,也就是說Shiro的對外API核心就是Subject庐椒;其每個API的含義:
0,ApplicationCode:應用程序代碼
1蚂踊,Subject:主體约谈,代表了當前的“用戶”,這個用戶不一定是一個具體的人,與當前應用交互的任何東西都是Subject棱诱,如網絡爬蟲泼橘,機器人等;即一個抽象概念迈勋;所有Subject都綁定到SercurityManager炬灭,與Subject的所有交互都會委托給SecurityManager;可以把Subject認為是一個門面靡菇;SecurityManager才是實際的執(zhí)行者重归;
2,SecurityManager:安全管理器厦凤;即所有與安全有關的操作都會與SecurityManager交互鼻吮;且它管理著所有Subject;可以看出它是Shiro的核心较鼓,它負責與后邊介紹的其他組件進行交互椎木,如果學習過SpringMVC,可以把SecurityManager看做是DispatcherServlet前端控制器博烂。
3香椎,Realm:域,Shiro從Realm獲取安全數(shù)據(jù)(如用戶禽篱,角色士鸥,權限),就是說SecurityManager要驗證用戶身份谆级,那么它需要從Realm獲取相應的用戶進行比較以確定用戶身份是否合法烤礁;也需要從Realm得到用戶相應的角色/權限進行驗證用戶是否能進行操作;可以把Realm看成DataSource肥照,即安全數(shù)據(jù)源
也就是脚仔,最簡單的一個Shiro應用:
1,應用代碼通過Subject來進行認證和授權舆绎,而Subject又委托給SecurityManager鲤脏;
2,我們需要給Shrio的SecurityManager注入Realm吕朵,從而讓SecurityManager能得到合法的用戶及其權限進行判斷猎醇,Shiro不提供維護用戶/權限,而是通過Realm讓開發(fā)人員自己注入努溃。
從Shiro內部來看Shiro架構:
1硫嘶,Subject:主體,可以看到主體可以是任何可以與應用交互的“用戶”梧税;
2沦疾,SecurityManager:相當于SpringMVC中的DispatcherServlet或者Struts2中的FilterDispatcher称近;是Shiro的心臟;所有具體的交互都通過SecurityManager進行控制哮塞;它管理著所有的Subject刨秆,且負責進行認證和授權,以及會話忆畅,緩存管理衡未。
3,Authenticator:認證器家凯,負責主體認證的眠屎,這是一個擴展點,如果用戶覺得Shiro默認的不好肆饶,可以自定義實現(xiàn),其需要認證策略(Authentication Strategy)即什么情況下算用戶認證通過了岖常;
4驯镊,Authrizer:授權器,或者訪問控制器竭鞍,用來決定主體是否有權限進行相應的操作板惑;即控制著用戶能訪問應用中的哪些功能;
5偎快,Realm冯乘;可以有1個或多個Realm,可以認為是安全實體數(shù)據(jù)源晒夹,即用于獲取安全實體的裆馒;可以是JDBC實現(xiàn),也可以是LDAP實現(xiàn)丐怯,或者內存實現(xiàn)等等喷好;由用戶提供;注意:Shiro不知道你的用戶/權限存儲在哪及何種格式存儲读跷;我們一般在應用中都需要實現(xiàn)自己的Realm梗搅;
6,SessionManager:如果寫過Servlet就應該知道Session的概念效览,Session需要有人去管理它的生命周期无切,這個組件就是SessionManager;而Shiro并不僅僅可以用在Web環(huán)境丐枉,也可以用在如普通的JavaSE環(huán)境哆键,EJB環(huán)境,所以呢瘦锹,Shiro就抽象了一個自己的Session來管理主體與應用之間交互的數(shù)據(jù)洼哎,這樣的話烫映,比如我們在Web環(huán)境用,剛開始是一臺Web服務器噩峦,接著有上了臺EJB服務器锭沟;這時如果把這兩臺服務器的會話數(shù)據(jù)放到一個地方,這個時候就可以實現(xiàn)自己的分布式會話(如把數(shù)據(jù)放到Memcached服務器)识补;
7族淮,SessionDAO:DAO大家都用過,數(shù)據(jù)庫訪問對象凭涂,用于會話的CRUD祝辣,比如我們想把Session保存到數(shù)據(jù)庫,那么可以實現(xiàn)自己的SessionDAO切油,通過如JDBC寫到數(shù)據(jù)庫蝙斜;比如想把Session放到Memcached中,可以實現(xiàn)自己的Memcached SessionDAO澎胡;另外SessionDAO中可以使用Cache進行緩存孕荠,以提高性能;
8攻谁,CacheManager:緩存控制器稚伍,來管理如用戶,角色戚宦,權限等的緩存的个曙;因為這些數(shù)據(jù)基本上很少去改變,放到緩存中后可以提高訪問的性能受楼。
Shiro涉及常見名詞
Subject: 主體 (用戶)
Security:安全()
Realm:領域垦搬,范圍(數(shù)據(jù)源 存儲數(shù)據(jù))
Authenticator: 認證器(認證操作)
Authentication:認證()
Authorizer: 授權器(授權操作)
Authorization: 授權()
Cryptography:? 加密 密碼()
Credential: 認證書 憑證(只有主體指導的安全值 ,如密碼 數(shù)字證書)
Matcher: 匹配器()
Principal: 身份(主體的標識屬性艳汽,可以使任何東西悼沿,用戶名,郵箱骚灸,身份證等 但是唯一的)
ini配置詳解
環(huán)境搭建實現(xiàn)簡單認證?利用ini?
Shiro內置的JDBCRealm講解
如何自定義Realm提供數(shù)據(jù)源?
MD5加密
加鹽就是往自己希望所希望加密的字段中添加字段進行干擾
迭代就是對字段進行加密加密幾次
認證器
授權器
Spring整合 實現(xiàn)登錄認證
配置文件編寫01
<!-- +++配置過濾器代理 -->web.xml
? <!--? DelegatingFilterProxy 簡單類名-->
? <!--注冊DelegatingFilterProxy: 通過代理模式將servlet 容器中的filet同Spring容器中的bean關聯(lián)起來? -->
? <filter>
? ? <filter-name>shiro</filter-name>
? ? <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
? ? <init-param>
? ? <!-- targetFilterLifecycle 該屬性為true表明啟用引入filter 的init()和destroy()撑帖,也就是說Spring在容器中對應的filter生命周期交給servlet容器管理 -->
? ? ? <param-name>targetFilterLifecycle</param-name>
? ? ? <param-value>true</param-value>
? ? </init-param>
? ? <!-- targetBeanName 目標bean對象的名稱? -->
? ? <!-- 該屬性設置Spring容器中filter的bean的ID -->
? ? <init-param>
? ? ? <param-name>targetBeanName</param-name>
? ? ? <param-value>shiroFilter</param-value>
? ? </init-param>
? </filter>
? <filter-mapping>
? ? <filter-name>shiro</filter-name>
? ? <url-pattern>/*</url-pattern>
? </filter-mapping>
配置文件編寫02
1祟绊,配置shiro.xml
1.1注冊憑證匹配器:
<!-- 注冊憑證匹配器 -->
? ? <!-- shiro-all.jar? 下的 HashedCred-->
? ? <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
? ? <!-- 加密算法的名稱? value MD5 -->
? ? <property name="hashAlgorithmName" value="md5"></property>
? ? <!-- 加密算法的迭代次數(shù)? value 2 -->
? ? <property name="hashIterations" value="2"></property>
? ? </bean>
? ? <!-- 注冊自定義realm? ? -->
? ? <bean id="customRealm" class="com.bjsxt.realm.CustomRealm">
? ? <!-- 設置注入 -指定憑證匹配器 -->
? ? <property name="credentialsMatcher" ref="credentialsMatcher"></property>
? ? </bean>
? ? <!-- 注冊 (安全管理器)securityManager -->
? ? <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
? ? <!-- 注入realm -->
? ? <property name="realms" ref="customRealm"></property>
? ? </bean>
? ? <!-- 注冊ShiroFilterFactoryBean ,注意:id名稱必須與web.xml中過濾器名稱對應-->
? ? <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
? ? <!-- 注入安全管理器 -->
? ? <property name="securityManager" ref="securityManager"></property>
? ? <!-- loginUrl? 登陸的URL 路徑 -->
? ? <property name="loginUrl" value="/user/login"></property>
? ? <!-- successUrl 登陸成功后跳轉的資源路徑 -->
? ? <property name="successUrl" value="/jsp/users.jsp"></property>
? ? <!-- unauthorizedUrl 指定未權限操作時跳轉的頁面 -->
? ? <property name="unauthorizedUrl" value="/jsp/refuse.jsp"></property>
? ? <!-- 設置過濾器鏈定義屬性:設置shiro內置的過濾器 -->
? ? <property name="filterChainDefinitions">
? ? <value>
? ? <!--如果訪問? /user/login? 時? 必須經過 表單驗證? authc(表單驗證的內置過濾器)-->
? ? /user/login=authc
? ? <!-- 其他所有資源都可以進行匿名訪問 anon? -->
? ? /**=anon
? ? </value>
? ? </property>
? ? </bean>
代碼編寫1?
注: 第一步是創(chuàng)建數(shù)據(jù)庫
1假瞬,創(chuàng)建實體類
2肝断,創(chuàng)建mapper接口以及mapper映射文件 以及sql語句
3,創(chuàng)建Service接口以及實現(xiàn)類
//根據(jù)用戶名查詢用戶信息
Users selectByUsername(String username);
實現(xiàn)類:
4丈钙,創(chuàng)建controller:
5非驮,創(chuàng)建Realm類
創(chuàng)建CustomRealm 并繼承 AuthorizingRealm? 重寫其方法
注:我們沒有吧service交給controller來管理 ,注入到了Realm中
代碼編寫2
Realm類:
@Autowired
private IUserService userService;
注意:
DelegatingFilterProxy源碼分析
實現(xiàn)注冊并密碼加密
1雏赦,先添加mapper 和mapper映射 中添加注冊劫笙;
2芙扎,添加service接口方法和service實現(xiàn)類
3,
實現(xiàn)菜單授權之實體類和mapper接口編寫01
導入ezui的包