javascript
志宇-Shiro-Spring
這里寫目錄標題
- Shiro有什么用
- Shiro架構
- 什么是身份認證
- 什么是授權
- 什么是會話管理
- 什么是加密
- Shiro認證流程
- Subject
- SecurityManager
- Authenticator
- Realm
- Authorizer
- Cryptography
- Cache Manager
- Shiro的使用
- 第一步:創建Relam實現類
- 認證
- 授權
- 第二步:創建SecurityManager實現類
- 第三步:將SecurityManager和Relam進行綁定,同時通過SecurityManager獲得對應的Subject
- 第四部:調用認證
- 第五步:進行授權
- 代碼
- 依賴
- java
Shiro有什么用
用于用戶登錄,權限攔截的使用
Shiro架構
什么是身份認證
Authentication,校驗用戶名和密碼是否可以登錄成功,可以登錄則創建一個jsessionid給客戶端
什么是授權
Authorization,將用戶所有的訪問權限查詢出來,存到內存或庫中
什么是會話管理
Session Management, 用戶的會話管理,多數情況下是web session,jsessionid不要存儲密碼,權限等信息
什么是加密
數據加解密,比如密碼加解密等,鹽值加密等 (Cryptography)
Shiro認證流程
Subject
我們把用戶或者程序稱為主體(如用戶,第三方服務,cron作業,爬蟲), 主體去訪問系統或者資源SecurityManager
安全管理器,Subject的認證和授權都要在安全管理器下進行Authenticator
認證器,主要負責Subject的認證Realm
數據域,Shiro和安全數據的連接器,好比jdbc連接數據庫; 通過realm獲取認證授權相關信息Authorizer
授權器,主要負責Subject的授權, 控制subject擁有的角色或者權限Cryptography
加解密,Shiro的包含易于使用和理解的數據加解密方法,簡化了很多復雜的apiCache Manager
緩存管理器,比如認證或授權信息,通過緩存進行管理,提高性能Shiro的使用
第一步:創建Relam實現類
創建一個或多個Relam類型的類(Relam接口有兩個方法要實現)
Relam接口的實現類有兩大作用(認證、授權)
1.它用于校驗登錄,校驗是否可以登錄,登錄成功則返回一個授權對象 (認證)
2.它用于檢查該用戶是否有指定角色或權限 (授權)
Relam詳情
shiro 自己定義了幾個Relam,我們可以將用戶、角色、權限等信息配置在文件中即可實現認證和授權,然而我們的權限信息要配置到庫中,所以要自己定義一個或者多個Relam實現類,來實現認證和授權。
認證
認證會調用如下方法
認證會調用Relam接口實現類的 如下方法
認證流程
授權
授權會調用如下方法
授權會調用Relam接口實現類的 如下方法
授權流程
第二步:創建SecurityManager實現類
SecurityManager實現類有什么用
SecurityManager用于用戶的注銷和登錄
登錄會返回一個Subject,Subject的一個成員變量是 SecurityManager
第三步:將SecurityManager和Relam進行綁定,同時通過SecurityManager獲得對應的Subject
//自己定義的realmCustomRealm customRealm = new CustomRealm();//Shiro校驗的核心對象DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();//將Relam 和 defaultSecurityManager 進行綁定defaultSecurityManager.setRealm(customRealm);SecurityUtils.setSecurityManager(defaultSecurityManager);//獲取當前操作的主體Subject subject = SecurityUtils.getSubject();第四部:調用認證
//用戶輸入的賬號密碼UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("jack", "123");//進行認證subject.login(usernamePasswordToken);System.out.println(" 認證結果:"+subject.isAuthenticated());//拿到用戶名System.out.println(" getPrincipal=" + subject.getPrincipal());第五步:進行授權
//進行授權subject.checkRole("role1");System.out.println("是否有對應的角色:"+subject.hasRole("role1"));System.out.println("是否有對應的權限:"+subject.isPermitted("video:add"));代碼
依賴
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.0</version> </dependency>java
Relam對象
package com.atguigu.shiro.test;import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection;import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set;/*** 自定義realm*/ public class CustomRealm extends AuthorizingRealm {private final Map<String,String> userInfoMap = new HashMap<>();{userInfoMap.put("jack","123");userInfoMap.put("xdclass","456");}//role -> permissionprivate final Map<String,Set<String>> permissionMap = new HashMap<>();{Set<String> set1 = new HashSet<>();Set<String> set2 = new HashSet<>();set1.add("video:find");set1.add("video:buy");set2.add("video:add");set2.add("video:delete");permissionMap.put("jack",set1);permissionMap.put("xdclass",set2);}//user -> roleprivate final Map<String,Set<String>> roleMap = new HashMap<>();{Set<String> set1 = new HashSet<>();Set<String> set2 = new HashSet<>();set1.add("role1");set1.add("role2");set2.add("root");roleMap.put("jack",set1);roleMap.put("xdclass",set2);}//進行權限校驗的時候會調用@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {System.out.println("權限 doGetAuthorizationInfo");String name = (String)principals.getPrimaryPrincipal();Set<String> permissions = getPermissionsByNameFromDB(name);Set<String> roles = getRolesByNameFromDB(name);SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();simpleAuthorizationInfo.setRoles(roles);simpleAuthorizationInfo.setStringPermissions(permissions);return simpleAuthorizationInfo;}//當用戶登陸的時候會調用@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println("認證 doGetAuthenticationInfo");//從token獲取身份信息,token代表用戶輸入的信息String name = (String)token.getPrincipal();//模擬從數據庫中取密碼String pwd = getPwdByUserNameFromDB(name);if( pwd == null || "".equals(pwd)){return null;}SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, pwd, this.getName());return simpleAuthenticationInfo;}/*** 模擬從數據庫獲取用戶角色集合* @param name* @return*/private Set<String> getRolesByNameFromDB(String name) {return roleMap.get(name);}/*** 模擬從數據庫獲取權限集合* @param name* @return*/private Set<String> getPermissionsByNameFromDB(String name) {return permissionMap.get(name);}private String getPwdByUserNameFromDB(String name) {return userInfoMap.get(name);} }調用類
package com.atguigu.shiro.test;import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.subject.Subject;public class Luck{public void testAuthentication() {//自己定義的realmCustomRealm customRealm = new CustomRealm();//Shiro校驗的核心對象DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();//將Relam 和 defaultSecurityManager 進行綁定defaultSecurityManager.setRealm(customRealm);SecurityUtils.setSecurityManager(defaultSecurityManager);//獲取當前操作的主體Subject subject = SecurityUtils.getSubject();//用戶輸入的賬號密碼UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("jack", "123");subject.login(usernamePasswordToken);//登錄System.out.println(" 認證結果:"+subject.isAuthenticated());//拿到主體標示屬性System.out.println(" getPrincipal=" + subject.getPrincipal());subject.checkRole("role1");System.out.println("是否有對應的角色:"+subject.hasRole("role1"));System.out.println("是否有對應的權限:"+subject.isPermitted("video:add"));}public static void main(String[] args) {new Luck().testAuthentication();} }總結
以上是生活随笔為你收集整理的志宇-Shiro-Spring的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 点云/网格模型的体积计算
- 下一篇: gamemaker学习笔记:读取JSON