shiro認證與授權
一.shiro認證方式-1(iniRealm)+授權
- 以maven項目為例
- 不采用數據庫,只使用shiro.ini的配置文件
1.添加依賴
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ym</groupId>
<artifactId>thirocode</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
</dependencies>
</project>
2.在resources包下新建shiro.ini的文件
- 如果文件名是shiro.ini,并且在resources包下,,在認證的時候可以不指定shiro.ini的文件路徑
[users]
zhenfu=zhenfu,admin,guest
caopi=caopi,guest
[roles]
admin=select,save,update,delete
guest=select,update
- 此為固定寫法
- 必須是[users]和[roles]
- [users] 之后是 : 賬戶=密碼,角色1,角色2
- [roles] 之后是 : 角色=權限1,權限2...
3.驗證信息
package service;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class TestShiro {
public static void main(String[] args) {
//1.構建securityManager環境
DefaultSecurityManager securityManager =new DefaultSecurityManager();
IniRealm iniRealm=new IniRealm("classpath:shiro.ini");
//如果shiro.ini寫在resources包下,可以不指定路徑
securityManager.setRealm(iniRealm);
//2.將SecurityManager設置到運行環境中
SecurityUtils.setSecurityManager(securityManager);
//3.創建一個Subject實例,該實例認證需要使用上面創建的SecurityManager
Subject subject = SecurityUtils.getSubject();
Scanner input =new Scanner(System.in);
System.out.println("請輸入用戶名:");
String username=input.next();
System.out.println("請輸入密碼:");
String password=input.next();
//創建token令牌,賬號和密碼是ini文件中配置的
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
try {
//4.用戶登錄
subject.login(token);
} catch (UnknownAccountException e) {
//System.out.println("用戶不存在");
e.printStackTrace();
}catch (IncorrectCredentialsException e) {
//System.out.println("密碼錯誤");
e.printStackTrace();
}catch (ExpiredCredentialsException e) {
//System.out.println("憑證過期");
e.printStackTrace();
} catch (AuthenticationException e) {
e.printStackTrace();
}
System.out.println("成功");
//判斷用戶是否屬于謀角色
System.out.println("判斷用戶是否屬于謀角色");
System.out.println(subject.hasRole("admin"));
System.out.println(subject.hasRole("guest"));
List<String> roles= Arrays.asList("admin","guest");
System.out.println(Arrays.toString(subject.hasRoles(roles)));
//判斷用戶是否屬于擁有謀權限
System.out.println("判斷用戶是否屬于擁有謀權限");
System.out.println(subject.isPermitted("save"));
System.out.println(subject.isPermitted("select"));
System.out.println(Arrays.toString(subject.isPermitted("select","update","save")));
}
}
二.shiro認證方式-2(jdbcRealm)
- 只是實現了簡單的認證,并沒有授權
- 和上一種認證方式采用的構建securityManager環境不同,新的shiro版本中IniSecurityManagerFactory已經廢除,但是在第二種方式使用最新的就會報錯,原因還在排查中,暫時使用老版本的shiro
1.添加依賴
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!--shiro的jdbcRealm認證所需要的jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.20</version>
<!--<scope>compile</scope>-->
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ym</groupId>
<artifactId>shiro_jdbcRealm</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!--shiro的jdbcRealm認證所需要的jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.20</version>
<!--<scope>compile</scope>-->
</dependency>
</dependencies>
</project>
2.2.在resources包下新建shiro.ini的文件
- 如果文件名是shiro.ini,并且在resources包下,,在認證的時候可以不指定shiro.ini的文件路徑
[main]
dmds=org.springframework.jdbc.datasource.DriverManagerDataSource
dmds.url=jdbc:mysql://localhost:3307/rbac?useSSL=false&serverTimezone=UTC&characterEncoding=utf-8
dmds.username=root
dmds.password=root
dmds.driverClassName=com.mysql.cj.jdbc.Driver
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$dmds
jdbcRealm.authenticationQuery=select password from user where username = ?
securityManager.realm=$jdbcRealm
3.測試類驗證
package service;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
public class TestShiroJDBCRealm {
//使用DefaultSecurityManager報錯,但是使用IniSecurityManagerFactory就可以運行,原因排查中
@Test
public void testJDBCRealm(){
// 構建SecurityManager工廠,IniSecurityManagerFactory可以從ini文件中初始化SecurityManager環境
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 通過工廠創建SecurityManager
SecurityManager manager = factory.getInstance();
// 將SecurityManager設置到運行環境中
SecurityUtils.setSecurityManager(manager);
//創建一個Subject實例,該實例認證需要使用上面創建的SecurityManager
Subject subject = SecurityUtils.getSubject();
//創建token令牌
UsernamePasswordToken token = new UsernamePasswordToken("yanm", "yanm");
//用戶登錄
subject.login(token);
System.out.println("success");
}
}
三.自定義Realm認證