当前环境:JDK1.8、eclipse、shiro1.4.1
1.导入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.0-alpha1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.0-alpha1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
</dependencies>
2.创建数据库
1.当前的role_permission表
2.当前的users表
3.当前的users_role表
3.编写自己的Facorty
import javax.sql.DataSource;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.util.Factory;
import com.alibaba.druid.pool.DruidDataSource;
/**
* @description 创建自定义的工厂用于生产部校验管理器
* @author hy
* @date 2019-10-04
*/
public class MyFactory implements Factory<org.apache.shiro.mgt.SecurityManager>{
//创建数据源
public DataSource getDataSource() {
DruidDataSource dataSource=new DruidDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("root");
System.out.println(dataSource);
return dataSource;
}
//获取Realm使用jdbcRealm
public Realm getRealm() {
JdbcRealm jdbcRealm = new JdbcRealm();
jdbcRealm.setDataSource(getDataSource());//这里是设置数据源
jdbcRealm.setAuthenticationQuery("select `password` from `users` where `username`=?");
jdbcRealm.setUserRolesQuery("select `role_name` from `users_role` where `username`=?");
jdbcRealm.setPermissionsQuery("select `permission_name` from `role_permission` where `role_name`=?");
jdbcRealm.setPermissionsLookupEnabled(true);
return jdbcRealm;
}
public org.apache.shiro.mgt.SecurityManager getInstance() {
DefaultSecurityManager securityManager=new DefaultSecurityManager(getRealm());
return securityManager;
}
}
在编写的时候出现的问题:
- 当前使用的mysql驱动变为了com.mysql.cj.jdbc.Driver
- 当前出现了
he server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support
.这个错误
需要在url的后面添加serverTimezone=UTC才不会报错 jdbcRealm.setPermissionsLookupEnabled(true)
;//这里表示启用用户的权限查询(这句话非常重要,没有这句话就会出现问题:不能查询用户的权限)- 注意在使用jdbc查询的时候,当前的用户和用户角色对应的数据库的表中不能使用角色1, 角色2…
这种方式必须分行启用
而当前的权限却可以使用权限1,权限2,权限3等
4.编写测试
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @description 使用jdbc方式访问数据库,并获取用户的权限,和信息
* @author admin
* @date 2019-10-04
*/
public class ShiroJdbcApp {
Logger log=LoggerFactory.getLogger(ShiroJdbcApp.class);
@Test
public void testSecurityMangaer() {
Factory<org.apache.shiro.mgt.SecurityManager> factory = new MyFactory();
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
AuthenticationToken token = new UsernamePasswordToken("zhangsan", "123456");
Subject subject = SecurityUtils.getSubject();
try {
subject.login(token);
log.info("用户登录成功!");
boolean hasRole = subject.hasRole("user");
log.info("用户是否有guest角色:"+hasRole);
if(hasRole) {
boolean hasDelete = subject.isPermitted("add");
log.info("用户是否有delete权限:"+hasDelete);
}
} catch (Exception e) {
log.error("用户登录失败!");
e.printStackTrace();
}
subject.logout();
}
}
5.测试
{
CreateTime:"2019-10-04 11:20:02",
ActiveCount:0,
PoolingCount:0,
CreateCount:0,
DestroyCount:0,
CloseCount:0,
ConnectCount:0,
Connections:[
]
}
十月 04, 2019 11:20:02 上午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
[main] INFO org.apache.shiro.session.mgt.AbstractValidatingSessionManager - Enabling session validation scheduler...
[main] INFO com.hy.shiro.jdbc.ShiroJdbcApp - 用户登录成功!
[main] INFO com.hy.shiro.jdbc.ShiroJdbcApp - 用户是否有guest角色:true
[main] INFO com.hy.shiro.jdbc.ShiroJdbcApp - 用户是否有delete权限:true
测试成功!
6.总结
1.使用当前shiro提供的jdbcRealm具有一定的缺陷,建议使用自定义的方式创建自己的Realm
2.在使用当前的新版本的数据库驱动的时候需要注意驱动类变为了:com.mysql.cj.jdbc.Driver
3.在提示中出现了url问题的时候(本身的url没有问题),需要在后面添加serverTimezone=UTC
4.在使用jdbcRealm的时候需要注意开启jdbcRealm.setPermissionsLookupEnabled(true)才会自动查询角色对应的权限
,未开启就不会查询角色对应的权限
5.使用jdbcRealm的时候注意数据库的用户角色和角色权限这两个表的编写样式
,写错可能导致出现问题!
以上纯属个人见解,如有问题请联系本人!`