自定义Realm
数据表设计
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `tb_permissions`
-- ----------------------------
DROP TABLE IF EXISTS `tb_permissions`;
CREATE TABLE `tb_permissions` (
`permission_id` int NOT NULL AUTO_INCREMENT,
`permission_code` varchar(60) DEFAULT NULL,
`permission_name` varchar(60) DEFAULT NULL,
PRIMARY KEY (`permission_id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of tb_permissions
-- ----------------------------
INSERT INTO `tb_permissions` VALUES ('1', 'sys:c:save', '入库');
INSERT INTO `tb_permissions` VALUES ('2', 'sys:c:delete', '出库');
INSERT INTO `tb_permissions` VALUES ('3', 'sys:c:update', '修改');
INSERT INTO `tb_permissions` VALUES ('4', 'sys:c:save', '查询');
INSERT INTO `tb_permissions` VALUES ('5', 'sys:x:save', '新增订单');
INSERT INTO `tb_permissions` VALUES ('6', 'sys:x:delete', '删除订单');
INSERT INTO `tb_permissions` VALUES ('7', 'sys:x:update', '修改订单');
INSERT INTO `tb_permissions` VALUES ('8', 'sys:x:find', '查询订单');
INSERT INTO `tb_permissions` VALUES ('9', 'sys:k:save', '新增客户');
INSERT INTO `tb_permissions` VALUES ('10', 'sys:k:delete', '删除客户');
INSERT INTO `tb_permissions` VALUES ('11', 'sys:k:update', '修改客户');
INSERT INTO `tb_permissions` VALUES ('12', 'sys:k:find', '查询客户');
-- ----------------------------
-- Table structure for `tb_roles`
-- ----------------------------
DROP TABLE IF EXISTS `tb_roles`;
CREATE TABLE `tb_roles` (
`role_id` int NOT NULL AUTO_INCREMENT,
`role_name` varchar(60) DEFAULT NULL,
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of tb_roles
-- ----------------------------
INSERT INTO `tb_roles` VALUES ('1', 'admin');
INSERT INTO `tb_roles` VALUES ('2', 'cmanager');
INSERT INTO `tb_roles` VALUES ('3', 'xmanager');
INSERT INTO `tb_roles` VALUES ('4', 'kmanager');
INSERT INTO `tb_roles` VALUES ('5', 'zmanager');
-- ----------------------------
-- Table structure for `tb_rps`
-- ----------------------------
DROP TABLE IF EXISTS `tb_rps`;
CREATE TABLE `tb_rps` (
`rid` int NOT NULL,
`pid` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of tb_rps
-- ----------------------------
INSERT INTO `tb_rps` VALUES ('2', '1');
INSERT INTO `tb_rps` VALUES ('2', '2');
INSERT INTO `tb_rps` VALUES ('2', '3');
INSERT INTO `tb_rps` VALUES ('2', '4');
INSERT INTO `tb_rps` VALUES ('3', '5');
INSERT INTO `tb_rps` VALUES ('3', '6');
INSERT INTO `tb_rps` VALUES ('3', '7');
INSERT INTO `tb_rps` VALUES ('3', '8');
INSERT INTO `tb_rps` VALUES ('3', '4');
INSERT INTO `tb_rps` VALUES ('3', '9');
INSERT INTO `tb_rps` VALUES ('3', '10');
INSERT INTO `tb_rps` VALUES ('3', '11');
INSERT INTO `tb_rps` VALUES ('3', '12');
INSERT INTO `tb_rps` VALUES ('4', '11');
INSERT INTO `tb_rps` VALUES ('4', '12');
INSERT INTO `tb_rps` VALUES ('5', '4');
INSERT INTO `tb_rps` VALUES ('5', '8');
INSERT INTO `tb_rps` VALUES ('5', '12');
-- ----------------------------
-- Table structure for `tb_urs`
-- ----------------------------
DROP TABLE IF EXISTS `tb_urs`;
CREATE TABLE `tb_urs` (
`uid` int NOT NULL,
`rid` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of tb_urs
-- ----------------------------
INSERT INTO `tb_urs` VALUES ('1', '1');
INSERT INTO `tb_urs` VALUES ('1', '2');
INSERT INTO `tb_urs` VALUES ('2', '2');
INSERT INTO `tb_urs` VALUES ('3', '3');
INSERT INTO `tb_urs` VALUES ('4', '4');
INSERT INTO `tb_urs` VALUES ('5', '5');
INSERT INTO `tb_urs` VALUES ('1', '3');
INSERT INTO `tb_urs` VALUES ('1', '4');
INSERT INTO `tb_urs` VALUES ('1', '5');
-- ----------------------------
-- Table structure for `tb_users`
-- ----------------------------
DROP TABLE IF EXISTS `tb_users`;
CREATE TABLE `tb_users` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`password_salt` varchar(60) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
-- Records of tb_users
-- ----------------------------
INSERT INTO `tb_users` VALUES ('1', 'niudun', '123456', null);
INSERT INTO `tb_users` VALUES ('2', 'kaipulei', '123456', null);
INSERT INTO `tb_users` VALUES ('3', 'aiyinsitan', '123456', null);
INSERT INTO `tb_users` VALUES ('4', 'maikesiwei', '123456', null);
INSERT INTO `tb_users` VALUES ('5', 'gaosi', '123456', null);
realm数据从dao层来,shiro认证需要用户信息
在新建一个springboot项目,其中的依赖(如下,给予参考)
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wh</groupId>
<artifactId>shirodemo2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shirodemo2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.wh.shirodemo2.Shirodemo2Application</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
配置application.yml
spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/db_shiro2?serverTimezone=CST&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=true
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
initial-size: 1
min-idle: 1
max-active: 20
mybatis:
mapper-locations: classpath:com/wh/mapper/*.xml
type-aliases-package: com.wh.shirodemo2.pojo
pojo层
package com.wh.shirodemo2.pojo;
import lombok.Data;
@Data
public class Users {
private Integer userId;
private String userName;
private String userPwd;
private String pwdSalt;
}
dao层
package com.wh.shirodemo2.dao;
import org.apache.ibatis.annotations.Mapper;
import java.util.Set;
@Mapper
public interface PermissionDao {
public Set<String> queryPermissionByUsername(String username)throws Exception;
}
package com.wh.shirodemo2.dao;
import org.apache.ibatis.annotations.Mapper;
import java.util.Set;
@Mapper
public interface RoleDao {
public Set<String> queryRoleNameByUsername(String username)throws Exception;
}
package com.wh.shirodemo2.dao;
import com.wh.shirodemo2.pojo.Users;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UsersDao {
Users queryUserByusername(String username) throws Exception;
}
对应的mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wh.shirodemo2.dao.PermissionDao">
<!-- 根据用户名查询权限列表-->
<select id="queryPermissionByUsername" resultSets="java.util.Set" resultType="string">
select tb_permissions.permission_code from tb_users
inner join tb_urs on tb_users.user_id=tb_urs.uid
inner join tb_roles on tb_urs.rid=tb_roles.role_id
inner join tb_rps on tb_roles.role_id=tb_rps.rid
inner join tb_permissions on tb_rps.pid=tb_permissions.permission_id
where tb_users.username=#{username}
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wh.shirodemo2.dao.RoleDao">
<!-- 根据名称查询角色-->
<select id="queryRoleNameByUsername" resultSets="java.util.Set" resultType="string">
select role_name from tb_users inner join tb_urs
on tb_users.user_id=tb_urs.uid
inner join
tb_roles
on tb_urs.uid=tb_roles.role_id
where tb_users.username=#{username}
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wh.shirodemo2.dao.UsersDao">
<resultMap id="userMap" type="Users">
<id column="user_id" property="userId"></id>
<result column="username" property="userName"></result>
<result column="password" property="userPwd"></result>
<result column="password_salt" property="pwdSalt"></result>
</resultMap>
<select id="queryUserByusername" resultMap="userMap">
select * from tb_users where username=#{username}
</select>
</mapper>
加依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.1.0</version>
</dependency>
自定义realm
package com.wh.shirodemo2.config;
import com.wh.shirodemo2.dao.PermissionDao;
import com.wh.shirodemo2.dao.RoleDao;
import com.wh.shirodemo2.dao.UsersDao;
import com.wh.shirodemo2.pojo.Users;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import javax.annotation.Resource;
import java.util.Set;
/**
* 创建一个类继承AuthorizingRealm,才叫realm类
* 重写这两个方法,
* 重写getName方法,返回当前realm的名称。
*/
public class MyRealm extends AuthorizingRealm {
@Resource
private UsersDao usersDao;
@Resource
private RoleDao roleDao;
@Resource
private PermissionDao permissionDao;
@Override
public String getName() {
return "myrealm";
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 获取授权信息
// 把当前用户的角色和权限查询出来
// 认证成功才能获取权限
String username = (String) principalCollection.iterator().next();
//获取当前用户的用户名
// 根据用户名查询用户的角色列表和权限列表
Set<String> rolename = roleDao.queryRoleNameByUsername(username);
Set<String> ps = permissionDao.queryPermissionByUsername(username);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(rolename);
info.setStringPermissions(ps);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 获取认证信息.认证的安全数据
//参数authenticationToken就是传递subject.login(token)
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
// 根据用户名从数据查询用户的安全数据
Users users = usersDao.queryUserByusername(username);
if (users==null){
return null;
}
AuthenticationInfo info= new SimpleAuthenticationInfo(username,users.getUserPwd(),getName());
return info;
}
}
shiroConfig
package com.wh.shirodemo2.config;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
@Configuration
public class ShiroConfig {
// shrio
// 自定义realm
@Bean
public MyRealm getMyrealm(){
MyRealm myRealm = new MyRealm();
return myRealm;
}
// securitymanager
@Bean
public DefaultWebSecurityManager getDefaultSecurityManager(MyRealm myRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// securityManager要完成效验,需要realm
securityManager.setRealm(myRealm);
return securityManager;
}
// 配置过滤器
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager){
ShiroFilterFactoryBean filter=new ShiroFilterFactoryBean();
filter.setSecurityManager(securityManager);
HashMap<String,String> filtermap = new HashMap<>();
filtermap.put("/","anon");
filtermap.put("/index.html","anon");
filtermap.put("/login.html","anon");
filtermap.put("/regist.html","anon");
filtermap.put("/user/login","anon");
filtermap.put("/layui/**","anon");
filtermap.put("/**","authc");
filter.setFilterChainDefinitionMap(filtermap);
filter.setLoginUrl("/login.html");
filter.setUnauthorizedUrl("/login.html");
return filter;
}
}
后面的service,controller,前端的内容可以复制博客shiro(一)里面的内容。