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认证
网友评论