feat:
- 添加JwtConfig - 添加Jwt工具类 - 添加Role RolePermission RoleUser实体类 - 修改User实体类,去除salt字段 - 添加自定义JwtUser类
This commit is contained in:
parent
6160c48c7b
commit
ee0109c876
16
pom.xml
16
pom.xml
@ -111,6 +111,22 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- JWT 工具:jjwt -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>0.11.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.11.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>0.11.5</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
31
src/main/java/asia/yulinling/workflow/config/JwtConfig.java
Normal file
31
src/main/java/asia/yulinling/workflow/config/JwtConfig.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package asia.yulinling.workflow.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* JWT配置类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author YLL
|
||||||
|
* @since 2025/6/11
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties(prefix = "jwt.config")
|
||||||
|
@Data
|
||||||
|
public class JwtConfig {
|
||||||
|
/**
|
||||||
|
* jwt 加密 key,默认值:kw.
|
||||||
|
*/
|
||||||
|
private String key = "kw";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jwt 过期时间,默认值:600000 {@code 10 分钟}.
|
||||||
|
*/
|
||||||
|
private Long ttl = 600000L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启 记住我 之后 jwt 过期时间,默认值 604800000 {@code 7 天}
|
||||||
|
*/
|
||||||
|
private Long remember = 604800000L;
|
||||||
|
}
|
||||||
@ -5,6 +5,8 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.security.config.Customizer;
|
import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ -21,4 +23,12 @@ public class SecurityConfig {
|
|||||||
.rememberMe(Customizer.withDefaults());
|
.rememberMe(Customizer.withDefaults());
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用默认密码加密
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,60 @@
|
|||||||
|
package asia.yulinling.workflow.model.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 权限
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author YLL
|
||||||
|
* @since 2025/6/11
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@TableName("`wk_permission`")
|
||||||
|
public class Permission {
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限名
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型为页面时,代表前端路由地址,类型为按钮时,代表后端接口地址
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限类型,页面-1,按钮-2
|
||||||
|
*/
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限表达式
|
||||||
|
*/
|
||||||
|
private String permission;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 父级Id
|
||||||
|
*/
|
||||||
|
private Long parentId;
|
||||||
|
}
|
||||||
54
src/main/java/asia/yulinling/workflow/model/entity/Role.java
Normal file
54
src/main/java/asia/yulinling/workflow/model/entity/Role.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package asia.yulinling.workflow.model.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 角色
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author YLL
|
||||||
|
* @since 2025/6/11
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("wk_role")
|
||||||
|
public class Role {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色名
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@TableField("create_time")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@TableField("update_time")
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package asia.yulinling.workflow.model.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 角色权限
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author YLL
|
||||||
|
* @since 2025/6/11
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("wk_role_permission")
|
||||||
|
public class RolePermission {
|
||||||
|
/**
|
||||||
|
* 角色id
|
||||||
|
*/
|
||||||
|
private Long roleId;
|
||||||
|
/**
|
||||||
|
* 权限id
|
||||||
|
*/
|
||||||
|
private Long permissionId;
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package asia.yulinling.workflow.model.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 角色用户
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author YLL
|
||||||
|
* @since 2025/6/11
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("wk_role_user")
|
||||||
|
public class RoleUser {
|
||||||
|
/**
|
||||||
|
* 权限id
|
||||||
|
*/
|
||||||
|
private Long roleId;
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
}
|
||||||
@ -46,11 +46,6 @@ public class User {
|
|||||||
*/
|
*/
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
/**
|
|
||||||
* 加密使用盐
|
|
||||||
*/
|
|
||||||
private String salt;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 邮箱
|
* 邮箱
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -0,0 +1,122 @@
|
|||||||
|
package asia.yulinling.workflow.model.vo.user;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 自定义User
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author YLL
|
||||||
|
* @since 2025/6/11
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UserPrincipal implements UserDetails {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户名
|
||||||
|
*/
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 昵称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密后的密码
|
||||||
|
*/
|
||||||
|
@JsonIgnore
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密使用盐
|
||||||
|
*/
|
||||||
|
@JsonIgnore
|
||||||
|
private String salt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邮箱
|
||||||
|
*/
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生日
|
||||||
|
*/
|
||||||
|
private String birthday;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性别,男-1,女-2
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号
|
||||||
|
*/
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 -1:删除 0:警用 1:启用
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次更新时间
|
||||||
|
*/
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次登录时间
|
||||||
|
*/
|
||||||
|
private Date lastLoginTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户角色列表
|
||||||
|
*/
|
||||||
|
private List<String > roles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户权限列表
|
||||||
|
*/
|
||||||
|
private Collection<? extends GrantedAuthority> authorities;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
103
src/main/java/asia/yulinling/workflow/utils/JwtUtil.java
Normal file
103
src/main/java/asia/yulinling/workflow/utils/JwtUtil.java
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package asia.yulinling.workflow.utils;
|
||||||
|
|
||||||
|
import asia.yulinling.workflow.config.JwtConfig;
|
||||||
|
import asia.yulinling.workflow.model.vo.user.UserPrincipal;
|
||||||
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import io.jsonwebtoken.*;
|
||||||
|
|
||||||
|
import java.security.Key;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* JWT工具类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author YLL
|
||||||
|
* @since 2025/6/11
|
||||||
|
*/
|
||||||
|
@EnableConfigurationProperties(JwtConfig.class)
|
||||||
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class JwtUtil {
|
||||||
|
private final JwtConfig jwtConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建JWT
|
||||||
|
*
|
||||||
|
* @param rememberMe 记住我
|
||||||
|
* @param id 用户id
|
||||||
|
* @param subject 用户名
|
||||||
|
* @param roles 用户角色
|
||||||
|
* @param authorities 用户权限
|
||||||
|
* @return JWT
|
||||||
|
*/
|
||||||
|
public String createJWT(Boolean rememberMe, Long id, String subject, List<String> roles, Collection<? extends GrantedAuthority> authorities) {
|
||||||
|
Date now = new Date();
|
||||||
|
|
||||||
|
Key key = Keys.hmacShaKeyFor(jwtConfig.getKey().getBytes());
|
||||||
|
|
||||||
|
JwtBuilder builder = Jwts.builder()
|
||||||
|
.setId(id.toString())
|
||||||
|
.setSubject(subject)
|
||||||
|
.setIssuedAt(now)
|
||||||
|
.signWith(key)
|
||||||
|
.claim("roles", roles)
|
||||||
|
.claim("authorities", authorities);
|
||||||
|
|
||||||
|
// 设置过期时间
|
||||||
|
Long ttl = rememberMe ? jwtConfig.getRemember() : jwtConfig.getTtl();
|
||||||
|
builder.setExpiration(new Date(now.getTime() + ttl));
|
||||||
|
|
||||||
|
return builder.compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建JWT
|
||||||
|
*
|
||||||
|
* @param authentication 用户认证信息
|
||||||
|
* @param rememberMe 记住我
|
||||||
|
* @return JWT
|
||||||
|
*/
|
||||||
|
public String createJWT(Authentication authentication, Boolean rememberMe) {
|
||||||
|
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
|
||||||
|
return createJWT(
|
||||||
|
rememberMe,
|
||||||
|
userPrincipal.getId(),
|
||||||
|
userPrincipal.getUsername(),
|
||||||
|
userPrincipal.getRoles(),
|
||||||
|
userPrincipal.getAuthorities()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Claims parseJWT(String jwt) {
|
||||||
|
try {
|
||||||
|
// 1. 构建密钥
|
||||||
|
Key key = Keys.hmacShaKeyFor(jwtConfig.getKey().getBytes());
|
||||||
|
|
||||||
|
// 2. 使用 parserBuilder 构建解析器
|
||||||
|
Jws<Claims> jws = Jwts.parserBuilder()
|
||||||
|
.setSigningKey(key)
|
||||||
|
.build()
|
||||||
|
.parseClaimsJws(jwt);
|
||||||
|
|
||||||
|
Claims claims = jws.getBody();
|
||||||
|
String id = claims.getId();
|
||||||
|
String username = claims.getSubject();
|
||||||
|
|
||||||
|
return claims;
|
||||||
|
} catch (ExpiredJwtException e) {
|
||||||
|
log.error("ExpiredJwtException", e);
|
||||||
|
throw new JwtException("ExpiredJwtException");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -36,4 +36,8 @@ spring.mail.properties.mail.smtp.starttls.required=true
|
|||||||
spring.mail.properties.mail.smtp.ssl.enable=false
|
spring.mail.properties.mail.smtp.ssl.enable=false
|
||||||
spring.mail.properties.mail.display.sendmail=spring-boot-demo
|
spring.mail.properties.mail.display.sendmail=spring-boot-demo
|
||||||
# Jasypt配置
|
# Jasypt配置
|
||||||
jasypt.encryptor.password=abc
|
jasypt.encryptor.password=abc
|
||||||
|
# JWT配置
|
||||||
|
jwt.config.key=kw
|
||||||
|
jwt.config.ttl=600000
|
||||||
|
jwt.config.remember=604800000
|
||||||
@ -5,7 +5,6 @@ CREATE TABLE `wk_user`
|
|||||||
`username` VARCHAR(32) NOT NULL UNIQUE COMMENT '用户名',
|
`username` VARCHAR(32) NOT NULL UNIQUE COMMENT '用户名',
|
||||||
`nickname` VARCHAR(32) NOT NULL UNIQUE COMMENT '昵称',
|
`nickname` VARCHAR(32) NOT NULL UNIQUE COMMENT '昵称',
|
||||||
`password` VARCHAR(32) NOT NULL COMMENT '加密后的密码',
|
`password` VARCHAR(32) NOT NULL COMMENT '加密后的密码',
|
||||||
`salt` VARCHAR(32) NOT NULL COMMENT '加密使用的盐',
|
|
||||||
`email` VARCHAR(32) NOT NULL UNIQUE COMMENT '邮箱',
|
`email` VARCHAR(32) NOT NULL UNIQUE COMMENT '邮箱',
|
||||||
`birthday` DATETIME DEFAULT NULL COMMENT '生日',
|
`birthday` DATETIME DEFAULT NULL COMMENT '生日',
|
||||||
`sex` INT(2) DEFAULT NULL COMMENT '性别,男-1,女-2',
|
`sex` INT(2) DEFAULT NULL COMMENT '性别,男-1,女-2',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user