shiro權限安全框架
- 什么是shiro 認證和授權
- 為什么要學shiro---安全
- 快速入門shiro
- 授權
什么是shiro 認證和授權
Apache Shiro 是Java 的一個安全框架,Shiro 可以非常容易的開發出足夠好的應用,其不僅可以用在JavaSE 環境,也可以用在JavaEE 環境,Shiro 可以幫助我們完成:認證【登陸】、授權【權限】、加密【密碼】、會話管理、與Web 集成、快取等,
為什么要學shiro—安全

subject: 理解為用戶;
securityManager: 安全管理 它是核心組件,
Authenticator: 認證器
Authorizer: 授權器,
Realm: 理解為和資料庫互動的一個組件,使用InitRealm—讀取ini檔案的內容,
快速入門shiro
(1)引入shiro-core的依賴
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.0</version>
</dependency>
(2)創建一個ini檔案 好比資料庫 必須叫 users表示用戶表
#表示用戶表 存放著賬戶和密碼
[users]
zs=111
ls=222
(3)測驗
退出登錄 :subject.logout();
判斷當前用戶是否認證成功:subject.isAuthenticated()
public static void main(String[] args) {
// 1.得到securityManager物件
DefaultSecurityManager securityManager = new DefaultSecurityManager();
// 2.設定securityManager管理的realm物件
securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
// 3.把securityManager系結到securityManager
SecurityUtils.setSecurityManager(securityManager);
// 4.獲取Subject物件
Subject subject = SecurityUtils.getSubject();
// 封裝賬戶和密碼
UsernamePasswordToken token = new UsernamePasswordToken("zs", "111");
try {
// 5.執行認證功能
subject.login(token);
System.out.println("賬戶和密碼正確");
} catch (Exception e){
e.printStackTrace();
System.out.println("賬戶和密碼錯誤");
}
// isAuthenticated判斷當前的用戶是否被認證
System.out.println("是否認證成功"+subject.isAuthenticated());
// 退出登錄
subject.logout();
// isAuthenticated判斷當前用戶是否認證成功
System.out.println("是否認證成功"+subject.isAuthenticated());
}
認證的流程:

流程如下:
首先呼叫 Subject.login(token) 進行登錄,其會自動委托給 Security Manager,呼叫之前必須通過 SecurityUtils.setSecurityManager() 設定;
SecurityManager 負責真正的身份驗證邏輯;它會委托給 Authenticator 進行身份驗證;
Authenticator 才是真正的身份驗證者,Shiro API 中核心的身份認證入口點,此處可以自定義插入自己的實作;
Authenticator 可能會委托給相應的 AuthenticationStrategy 進行多 Realm 身份驗證,默認 ModularRealmAuthenticator 會呼叫 AuthenticationStrategy 進行多 Realm 身份驗證;
Authenticator 會把相應的 token 傳入 Realm,從 Realm 獲取身份驗證資訊,如果沒有回傳 / 拋出例外表示身份驗證失敗了,此處可以配置多個 Realm,將按照相應的順序及策略進行訪問,
授權
(1)在ini檔案中
#表示用戶表 存放著賬戶和密碼
[users]
zs=111,admin
ls=222,role1
#表示角色表 包含角色的名稱 角色具有的權限
[roles]
admin=user:query,user:delete,user:update,user:insert
role1=user:query
role2=user:query,user:update
role3=user:export
(2)測驗授權,注意認證之后,再進行授權
當前認證后的用戶是否具有user:query:subject.isPermitted(“user:query”)
當前認證后的用戶是否具有多個權限:subject.isPermittedAll(“user:query”,“user:export”)
部分測驗代碼:
// 授權
System.out.println("當前認證后的用戶是否具有user:query:"+subject.isPermitted("user:query"));
System.out.println("當前認證后的用戶是否具有多個權限:"+subject.isPermittedAll("user:query","user:export"));
}
完整測驗代碼:
// 1.得到securityManager物件
DefaultSecurityManager securityManager = new DefaultSecurityManager();
// 2.設定securityManager管理的realm物件
securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
// 3.把securityManager系結到securityManager
SecurityUtils.setSecurityManager(securityManager);
// 4.獲取Subject物件
Subject subject = SecurityUtils.getSubject();
// 封裝賬戶和密碼
UsernamePasswordToken token = new UsernamePasswordToken("zs", "111");
try {
// 5.執行認證功能
subject.login(token);
System.out.println("賬戶和密碼正確");
} catch (Exception e){
e.printStackTrace();
System.out.println("賬戶和密碼錯誤");
}
// isAuthenticated判斷當前的用戶是否被認證
System.out.println("是否認證成功"+subject.isAuthenticated());
/*// 退出登錄
subject.logout();
// isAuthenticated判斷當前用戶是否認證成功
System.out.println("是否認證成功"+subject.isAuthenticated());*/
// 授權
System.out.println("當前認證后的用戶是否具有user:query:"+subject.isPermitted("user:query"));
System.out.println("當前認證后的用戶是否具有多個權限:"+subject.isPermittedAll("user:query","user:export"));
**注意:**上面這些代碼都是ini資料,實際開發肯定通過資料庫進行的判斷,
根據iniRealm創建自己的realm類,該類中就可以寫自己連接資料庫的內容,
創建MyRealm繼承AuthorizingRealm,并重寫doGetAuthorizationInfo和doGetAuthenticationInfo的方法
自己創建MyRealm類
系結權限 SimpleAuthorizationInfo
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addStringPermissions(permission);
SimpleAuthenticationInfo類中的三個引數代表的意思:
Object principal,賬號 可以被登錄成功后獲取,還可以傳給授權的方法
Object credentials,從資料庫中查詢的密碼
String realmName 當前realm的名稱
認證
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassWord(),this.getName());
this.getName()表示呼叫父類的方法
package com.myrealm;
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.List;
/**
* @author : 小崢
* @date : 2021/4/5 0:46
* @description:
*/
public class MyRealm extends AuthorizingRealm {
/* @AutoWird
private UserService userService;*/
private UserService userService = new UserService();
// 當執行授權時呼叫該方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user = (User) principalCollection.getPrimaryPrincipal();
System.out.println("授權方法的執行"+user);
// 根據用戶id擦混該用戶具有的權限碼
List<String> permission=userService.findPermissionById(user.getId());
// 系結權限
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addStringPermissions(permission);
return info;
}
//當執行認證功能時呼叫該方法 認證時捕獲例外
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("認證方法的執行");
// 得到賬戶 唯一的標識
String loginName = authenticationToken.getPrincipal().toString();
// System.out.println("你登錄的賬戶值為:" + loginName);
// 呼叫service中的方法 根據用戶名查詢用戶資訊
User user = userService.findByLoginName(loginName);
if (user!=null){
// Object principal,賬號 可以被登錄成功后獲取,還可以傳給授權的方法
// Object credentials,從資料庫中查詢的密碼
// String realmName 當前realm的名稱
// SimpleAuthenticationInfo info = new SimpleAuthenticationInfo("hhhhhhh",user.getPassWord(),this.getName());
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassWord(),this.getName());
return info;
}
return null;
}
}
service層
public class UserService {
public User findByLoginName(String loginName) {
switch (loginName) {
case "admin":
return new User(1, "admin", "111", "管理員");
case "zs":
return new User(2, "zzz", "222", "張三");
case "ls":
return new User(3, "lll", "333", "李四");
default:
return null;
}
}
public List<String> findPermissionById(int id) {
List<String> list=new ArrayList<>();
if (id==1){
list.add("user:query");
list.add("user:delete");
list.add("user:update");
list.add("user:insert");
}else if (id==2){
list.add("user:query");
}else if (id==3){
list.add("user:delete");
list.add("user:update");
}
return list;
}
}
測驗類
public class Demo {
public static void main(String[] args) {
// 得到SecurityManager物件
DefaultSecurityManager securityManager = new DefaultSecurityManager();
// 設定securityManager管理的realm物件
MyRealm myRealm = new MyRealm();
securityManager.setRealm(myRealm);
// 把securityManager系結到SecurityUtilss
SecurityUtils.setSecurityManager(securityManager);
// 獲取subject物件
Subject subject = SecurityUtils.getSubject();
// 封裝賬戶和密碼
UsernamePasswordToken token=new UsernamePasswordToken("zs","222");
subject.login(token);
Object principal = subject.getPrincipal();
System.out.println(principal);
// 認證-->登錄
System.out.println("認證成功:"+subject.isAuthenticated());
// 只有認證之后才能執行MyRealm中的認證方法
System.out.println("查詢權限:"+subject.isPermittedAll("user:query"));
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/273330.html
標籤:其他
