一 点睛
分析JdbcRealm源码,可知JdbcRealm封装了默认的查询规则
public class JdbcRealm extends AuthorizingRealm {
protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";
protected static final String DEFAULT_SALTED_AUTHENTICATION_QUERY = "select password, password_salt from users where username = ?";
protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";
protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";
......
}
下面分使用默认查询和不使用默认查询两种方法进行实战
二 实战
1 新建pom
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
<!--引入数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<!--引入数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.20</version>
</dependency>
</dependencies>
2 默认查询语句方式
2.1 新建数据库和数据表,脚本如下:
drop database if exists shiro;
CREATE DATABASE `shiro` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
use shiro;
create table users (
id bigint auto_increment,
username varchar(100),
password varchar(100),
password_salt varchar(100),
constraint pk_users primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_users_username on users(username);
create table user_roles(
id bigint auto_increment,
username varchar(100),
role_name varchar(100),
constraint pk_user_roles primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_user_roles on user_roles(username, role_name);
create table roles_permissions(
id bigint auto_increment,
role_name varchar(100),
permission varchar(100),
constraint pk_roles_permissions primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_roles_permissions on roles_permissions(role_name, permission);
其中users、user_roles和roles_permissions数据表数据如下
2.2 新建测试类
package com.liuyanzhao.test;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
public class JdbcRealmTest {
DruidDataSource dataSource = new DruidDataSource();
{
dataSource.setUrl("jdbc:mysql://localhost:3306/shiro");
dataSource.setUsername("root");
dataSource.setPassword("123456");
}
@Test
public void testAuthentication() {
JdbcRealm jdbcRealm = new JdbcRealm();
jdbcRealm.setDataSource(dataSource);
jdbcRealm.setPermissionsLookupEnabled(true);//设置权限开关,默认是false
//1、构建SecurityManager环境
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
defaultSecurityManager.setRealm(jdbcRealm);
//2、主体提交认证请求
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("Tom","123456");
subject.login(token);
System.out.println("isAuthenticated:"+subject.isAuthenticated());
subject.checkRole("admin");
subject.checkRoles("admin","user");
subject.checkPermission("user:select");
}
}
2.3 测试结果
isAuthenticated:true
Process finished with exit code 0
3 自定义查询语句方式
3.1 新建数据表test_user、test_user_role、test_roles_permissions,它们的数据如下:
mysql> select * from test_user_role;
+-----------+-----------+
| user_name | role_name |
+-----------+-----------+
| xiaoming | user |
+-----------+-----------+
1 row in set (0.00 sec)
mysql> select * from test_user;
+-----------+----------+
| user_name | password |
+-----------+----------+
| xiaoming | 654321 |
+-----------+----------+
1 row in set (0.00 sec)
mysql> select * from test_roles_permissions;
+----+-----------+-------------+
| id | role_name | permission |
+----+-----------+-------------+
| 1 | user | user:select |
+----+-----------+-------------+
1 row in set (0.00 sec)
3.2 新建测试类
package com.myimooc.shiro.test;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
/**
* @className: JdbcRealmTest
* @description: JdbcRealmTest测试类
* @date: 2020/5/12
* @author: cakin
*/
public class JdbcRealmTest {
/**
* 定义数据源
*/
private DruidDataSource dataSource = new DruidDataSource();
{
dataSource.setUrl("jdbc:mysql://localhost:3306/shiro?useUnicode=true&characterEncoding=utf8&useSSL=false");
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
}
@Test
public void testAuthentication() {
// 权限数据从数据库获取
JdbcRealm jdbcRealm = new JdbcRealm();
// 设置jdbcrealm的数据源
jdbcRealm.setDataSource(dataSource);
// 启用到数据库查询权限数据(默认值:false)
jdbcRealm.setPermissionsLookupEnabled(true);
// 使用自定义SQL
// 等价于默认 protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";
String sql = "select password from test_user where user_name = ?";
jdbcRealm.setAuthenticationQuery(sql); // 改变login默认sql
// 等价于默认 protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";
String roleSql = "select role_name from test_user_role where user_name = ?";
jdbcRealm.setUserRolesQuery(roleSql); // 改变checkRole默认sql
// 等价于默认 protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";
String persionSql = "select permission from test_roles_permissions where role_name = ?";
jdbcRealm.setPermissionsQuery(persionSql); // 改变checkPermission默认sql
// 构建 SecurityManager
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
defaultSecurityManager.setRealm(jdbcRealm);
// 主体提交认证请求
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("xiaoming", "654321");
subject.login(token);
subject.checkRole("user");
subject.checkPermission("user:select");
// 是否认证
System.out.println("isAuthenticated:" + subject.isAuthenticated());
}
}
3.3 测试结果
isAuthenticated:true
Process finished with exit code 0