shiro框架java使用
大綱
Shiro簡介及架構圖講解
ini配置檔案講解
Shiro搭建及簡單認證實現
加密及憑證匹配器
Spring整合Shiro完成登入功能.
知識點詳解
一、Shiro簡介
1.Shiro一個Java許可權框架.
1.1在專案中把涉及到許可權的業務提出來用shiro完成.
2.Shiro架構圖
2.1 Subject 主體.對應一個使用者,使用者所有的資訊都存放在Subject中.無論什麼程式語言只要有Subject都可以使用Shiro框架.
2.2 Cryptography: Shiro密碼管理功能.
2.2.1 密碼加密,加鹽,迭代等等.
2.3 Security Manager: 許可權管理器.Shiro核心內容.所有Shiro功能都封裝到Security Manager
2.4 Authenticator: 認證器. 例如登入註冊等功能就屬性認證功能.
2.5 Authorizer:授權器. 例如:判斷使用者是否具有某個角色,判斷使用者是否有某個許可權,判斷使用者可以訪問的選單.
2.6 Session Manager : Session管理器.使用Shiro後,shiro會禁用HttpSession,使用Shiiro自己的Session管理器.
2.7 Cache Manager : 快取管理. 支援Cookie的快取(remember me),支援Redis的快取.
2.8 Realm: 域.作用是當Shiro希望訪問資料庫時,通過Realm元件完成的.
二、Shiro.ini檔案
1.ini (InitializationFile) 初始檔案.Window系統副檔名.
2.Shiro 使用時可以連線資料庫,也可以不連線資料庫.
2.1 如果不連線資料庫,可以在shiro.ini中配置靜態資料.
3. Shiro.ini檔案組成部分
3.1[main] :定義全域性變數
3.1.1 內建securityManager物件.
3.1.2 操作內建物件時,在[main]裡面寫東西\
[main] securityManager.屬性=值
myobj=com.bjsxt.lei securityManager.物件屬性=$myobj |
3.2[users] :定義使用者名稱和密碼
[users] # 定義使用者名稱為zhangsan 密碼為zs zhangsan=zs # 定義使用者名稱lisi密碼為lisi同時具有role1和role2兩個角色 lisi=lisi,role1,role2 |
3.3[roles]: 定義角色
[roles] role1=許可權名1,許可權名2 role2=許可權3,許可權4 |
3.4[urls] : 定義哪些內建urls生效.在web應用時使用.
[urls] url地址=內建filter或自定義filter # 訪問時出現/login的url必須去認證.支援authc對應的Filter /login=authc # 任意的url都不需要進行認證等功能. /** = anon # 所有的內容都必須保證使用者已經登入. /**=user # url abc 訪問時必須保證使用者具有role1和role2角色. /abc=roles[“role1,role2”] |
三、Shiro 環境搭建實現認證
認證流程
實現步驟
2.1 在pom.xml中匯入jar
<dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version> </dependency> <!-- <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> --> </dependencies> |
2.2 在src /java/resources下新建shiro.ini檔案
[users] zhangsan=zs |
2.3 編寫程式碼,實現認證
// SecurityManager JDK也有這個類,在java.lang包 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); SecurityManager sm = factory.getInstance(); // 只要執行緒不變,Subject不變 SecurityUtils.setSecurityManager(sm); Subject subject = SecurityUtils.getSubject(); // Subject subject = (new Subject.Builder()).buildSubject(); // 客戶端傳遞過來的使用者名稱和密碼 UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "zs"); try { subject.login(token); System.out.println("登入成功"); } catch (UnknownAccountException e) { System.out.println("賬戶不存在"); } catch (IncorrectCredentialsException e) { System.out.println("密碼錯誤"); } |
四、實現授權
1.流程圖
2.常用api
2.1 subject.hasRole(“”); 判斷是否有角色
2.2 subject.hashRoles(List);分別判斷使用者是否具有List中每個內容
2.3 subject.hasAllRoles(Collection);返回boolean,要求引數中所有角色使用者都需要具有.
2.4 subject.isPermitted(“”);判斷是否具有許可權.
五、自定義Realm
1. Principal:身份
1.1 使用者名稱可以是身份
1.2 郵箱可以是身份.
1.3 手機可以是身份.
1.4 使用者物件也可以是身份.
2.Credentials:憑證.
2.1 密碼可以是憑證
2.2 證書也是可以是憑證.
3. SecurityManager介面只有一個普通java類DefaultSecurityManager
4. 實現步驟:
4.1 新建類繼承AuthorizingRealm
4.2 在doGetAuthenticationInfo實現認證過程.
4.3 程式碼
public class MyRealm extends AuthorizingRealm{
//執行授權方法 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // TODO Auto-generated method stub return null; } //執行認證 //當subject.login()時自動呼叫該方法 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { Object obj = token.getPrincipal(); System.out.println("principal:"+obj); Object obj2 = token.getCredentials(); new String((char[])obj2); System.out.println("credentials:"+new String((char[])obj2));
//如果方法返回值為null,shiro認為使用者名稱不存在. //如果返回值不是null,判斷AuthenticationInfo中憑證和subject.login時憑證是否匹配 //第一個引數: 第一個引數寫什麼以後登入這個使用者的身份就是什麼. //第二個引數是從資料庫中取出的憑證資訊,判斷這個資訊和subject.login()第二個引數是否匹配. //第三個引數:都是使用者主鍵值. SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(obj, "zs", "myrealm"); return info; }
} |
4.4 在shiro.ini中配置自定義Realm
[main] myrealm=com.bjsxt.realm.MyRealm
securityManager.realms=$myrealm |
4.5 執行subject.login()呼叫doGetAuthenticationInfo
六. 憑證匹配器
1. 保證資料庫中密碼是加密的密碼
2.在shiro.ini中配置憑證匹配器
[main] myrealm=com.bjsxt.realm.MyRealm # 定義憑證匹配器類 credentialsMatcher =org.apache.shiro.authc.credential.HashedCredentialsMatcher # 設定加密演算法 credentialsMatcher.hashAlgorithmName=md5 # 迭代次數 credentialsMatcher.hashIterations=2 # 引用憑證匹配器 myrealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$myrealm |
3.在自定義realm中
3.1 第三個引數:加鹽值. 型別是ByteSource型別,bytes()跟字串型別,不能使用Long
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(),rs.getObject("password"), ByteSource.Util.bytes(rs.getObject("id").toString()) ,"key:"+rs.getObject("id")); |
七、自定義Realm中-doGetAuthorizationInfo()
1.該方法被執行情況
- java中hasRole() , isPermitted();
- 使用註解
@RequiresRoles("role1") @RequiresPermissions("") |
2.在jsp中標籤
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<shiro:hasRole name="role1"> abc </shiro:hasRole> <shiro:hasPermission name="quanxian"> jqk </shiro:hasPermission>
|