springboot 2.7.6 security mysql redis jwt配置例子
数据库结构用的是若依的数据库基本结构,ruoyi.vip。
总体参考了文章:https://blog.csdn.net/qq_45847507/article/details/126681110
本文章只包含不同的地方,相同的不再赘述。
1、创建spring工程,jdk1.8,maven。
pom.xml中依赖部分的文件内容:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--fastjson依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.33</version>
</dependency>
<!--jwt依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2、application.yml的文件内容:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mall?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
redis:
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码
password: 123456
# Redis数据库索引
database: 3
# 连接超时时间(毫秒)
timeout: 30000
lettuce:
pool:
max-active: 50
max-wait: -1
max-idle: 50
min-idle: 1
logging:
level:
root: info
3、实体类:
LoginUser.java
package com.rainpet.springsecurity.entity;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@Data
@NoArgsConstructor
public class LoginUser implements UserDetails {
private SysUser user;
//存储权限信息
private List<String> permissions;
public LoginUser(SysUser user,List<String> permissions) {
this.user = user;
this.permissions = permissions;
}
//存储SpringSecurity所需要的权限信息的集合
@JSONField(serialize = false)
private List<GrantedAuthority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
if(authorities!=null){
return authorities;
}
//把permissions中字符串类型的权限信息转换成GrantedAuthority对象存入authorities中
authorities = permissions.stream().
map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
return authorities;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUserName();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
SysMenu.java
package com.rainpet.springsecurity.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 菜单权限表(SysMenu)实体类
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "sys_menu")
public class SysMenu implements Serializable {
private static final long serialVersionUID = -40356785423868312L;
/**
* 菜单ID
*/
@TableId
private Long menuId;
/**
* 菜单名称
*/
private String menuName;
/**
* 父菜单ID
*/
private Long parentId;
/**
* 显示顺序
*/
private Integer orderNum;
/**
* 路由地址
*/
private String path;
/**
* 组件路径
*/
private String component;
/**
* 路由参数
*/
private String query;
/**
* 路由名称
*/
private String routeName;
/**
* 是否为外链(0是 1否)
*/
private Boolean isFrame;
/**
* 是否缓存(0缓存 1不缓存)
*/
private Boolean isCache;
/**
* 菜单类型(M目录 C菜单 F按钮)
*/
private String menuType;
/**
* 菜单状态(0显示 1隐藏)
*/
private String visible;
/**
* 菜单状态(0正常 1停用)
*/
private String status;
/**
* 权限标识
*/
private String perms;
/**
* 菜单图标
*/
private String icon;
/**
* 创建者
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新者
*/
private String updateBy;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 备注
*/
private String remark;
}
SysRole.java
package com.rainpet.springsecurity.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 角色信息表(SysRole)实体类
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "sys_role")
public class SysRole implements Serializable {
private static final long serialVersionUID = -40356785423868312L;
/**
* 角色ID
*/
@TableId
private Long roleId;
/**
* 角色名称
*/
private String roleName;
/**
* 角色权限字符串
*/
private String roleKey;
/**
* 显示顺序
*/
private Integer roleSort;
/**
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
*/
private String dataScope;
/**
* 菜单树选择项是否关联显示
*/
private Boolean menuCheckStrictly;
/**
* 部门树选择项是否关联显示
*/
private Boolean deptCheckStrictly;
/**
* 角色状态(0正常 1停用)
*/
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
private String delFlag;
/**
* 创建者
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新者
*/
private String updateBy;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 备注
*/
private String remark;
}
SysUser.java
package com.rainpet.springsecurity.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 用户信息表(SysUser)实体类
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "sys_user")
public class SysUser implements Serializable {
private static final long serialVersionUID = -40356785423868312L;
/**
* 用户ID
*/
@TableId
private Long userId;
/**
* 部门ID
*/
private Long deptId;
/**
* 用户账号
*/
private String userName;
/**
* 用户昵称
*/
private String nickName;
/**
* 用户类型(00系统用户)
*/
private String userType;
/**
* 用户邮箱
*/
private String email;
/**
* 手机号码
*/
private String phonenumber;
/**
* 用户性别(0男 1女 2未知)
*/
private String sex;
/**
* 头像地址
*/
private String avatar;
/**
* 密码
*/
private String password;
/**
* 帐号状态(0正常 1停用)
*/
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
private String delFlag;
/**
* 最后登录IP
*/
private String loginIp;
/**
* 最后登录时间
*/
private LocalDateTime loginDate;
/**
* 创建者
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新者
*/
private String updateBy;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 备注
*/
private String remark;
}
4、mapper
SysMenuMapper.java
package com.rainpet.springsecurity.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rainpet.springsecurity.entity.SysMenu;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SysMenuMapper extends BaseMapper<SysMenu> {
List<String> selectPermsByUserId(Long id);
}
SysRoleMapper.java
package com.rainpet.springsecurity.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rainpet.springsecurity.entity.SysRole;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SysRoleMapper extends BaseMapper<SysRole> {
}
SysUserMapper.java
package com.rainpet.springsecurity.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rainpet.springsecurity.entity.SysUser;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
}
5、其他问题
SysMenuMapper.xml
<?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.rainpet.springsecurity.mapper.SysMenuMapper">
<select id="selectPermsByUserId" resultType="java.lang.String">
SELECT
DISTINCT (case when m.`perms`='' then `path` else m.`perms` end)
FROM
sys_user_role ur
LEFT JOIN `sys_role` r ON ur.`role_id` = r.`role_id`
LEFT JOIN `sys_role_menu` rm ON ur.`role_id` = rm.`role_id`
LEFT JOIN `sys_menu` m ON m.`menu_id` = rm.`menu_id`
WHERE
user_id = #{userid}
</select>
</mapper>