Apache Shiro中连接MySQL数据库完成授权和认证(使用jdbcRealm类完成)

当前环境: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;
	}
}

在编写的时候出现的问题:

  1. 当前使用的mysql驱动变为了com.mysql.cj.jdbc.Driver
  2. 当前出现了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才不会报错
  3. jdbcRealm.setPermissionsLookupEnabled(true);//这里表示启用用户的权限查询(这句话非常重要,没有这句话就会出现问题:不能查询用户的权限)
  4. 注意在使用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的时候注意数据库的用户角色和角色权限这两个表的编写样式,写错可能导致出现问题!

以上纯属个人见解,如有问题请联系本人!`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值