Java实现JWT 双签发认证+RBAC权限的示例代码

 更新时间:2025年08月24日 10:59:59   作者:hqxstudying  
本文主要介绍了Java实现JWT 双签发认证+RBAC权限的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1. JWT 双签发认证基础概念

JWT(JSON Web Token)是一种用于在网络应用间传递声明的安全标准。双签发认证指的是同时签发访问令牌(Access Token)和刷新令牌(Refresh Token):

  • Access Token:包含用户身份和权限信息,有效期较短(如 15 分钟)
  • Refresh Token:仅包含用户身份信息,有效期较长(如 7 天)
  • 当 Access Token 过期时,使用 Refresh Token 重新获取新的 Access Token

2. RBAC 权限模型基础概念

RBAC(基于角色的访问控制)是一种权限管理模型,核心组件包括:

  • 用户(User):系统的使用者
  • 角色(Role):一组权限的集合(如管理员、用户、访客)
  • 权限(Permission):对资源的操作许可(如创建文章、删除用户)
  • 用户 - 角色关联:一个用户可以拥有多个角色
  • 角色 - 权限关联:一个角色可以包含多个权限

3. Java 项目中实现 JWT 双签发认证

以下是一个简单的 Java 实现示例,使用 Spring Security 和 JJWT 库:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
 
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
 
@Component
public class JwtUtil {
    private static final String SECRET_KEY = "your-secret-key";
    private static final long ACCESS_TOKEN_VALIDITY = 15 * 60 * 1000; // 15分钟
    private static final long REFRESH_TOKEN_VALIDITY = 7 * 24 * 60 * 60 * 1000; // 7天
 
    // 生成访问令牌
    public String generateAccessToken(String username, String roles) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("roles", roles);
        return createToken(claims, username, ACCESS_TOKEN_VALIDITY);
    }
 
    // 生成刷新令牌
    public String generateRefreshToken(String username) {
        return createToken(new HashMap<>(), username, REFRESH_TOKEN_VALIDITY);
    }
 
    private String createToken(Map<String, Object> claims, String subject, long validity) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + validity))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }
 
    // 验证令牌
    public Boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
 
    // 从令牌中获取用户名
    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }
 
    // 从令牌中获取角色
    public String getRolesFromToken(String token) {
        return (String) getAllClaimsFromToken(token).get("roles");
    }
 
    private <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }
 
    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
    }
}

4. Java 项目中实现 RBAC 权限控制

下面是一个基于 Spring Security 的 RBAC 实现示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 
@Configuration
@EnableWebSecurity
public class SecurityConfig {
 
    private final JwtRequestFilter jwtRequestFilter;
 
    public SecurityConfig(JwtRequestFilter jwtRequestFilter) {
        this.jwtRequestFilter = jwtRequestFilter;
    }
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/api/auth/**").permitAll() // 认证接口不需要权限
                .antMatchers("/api/admin/**").hasRole("ADMIN") // 需要ADMIN角色
                .antMatchers("/api/user/**").hasAnyRole("ADMIN", "USER") // 需要ADMIN或USER角色
                .anyRequest().authenticated()
                .and()
            .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        
        return http.build();
    }
}

5. 数据库五层设计方案

一个完整的 RBAC 系统数据库设计通常包含以下五层:

第一层:用户层

CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    status TINYINT NOT NULL DEFAULT 1,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

第二层:角色层

CREATE TABLE roles (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    role_name VARCHAR(50) UNIQUE NOT NULL,
    description VARCHAR(255),
    status TINYINT NOT NULL DEFAULT 1,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

第三层:权限层

CREATE TABLE permissions (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    permission_name VARCHAR(50) UNIQUE NOT NULL,
    description VARCHAR(255),
    status TINYINT NOT NULL DEFAULT 1,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

第四层:关联层

-- 用户-角色关联表
CREATE TABLE user_roles (
    user_id BIGINT NOT NULL,
    role_id BIGINT NOT NULL,
    PRIMARY KEY (user_id, role_id),
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (role_id) REFERENCES roles(id)
);
 
-- 角色-权限关联表
CREATE TABLE role_permissions (
    role_id BIGINT NOT NULL,
    permission_id BIGINT NOT NULL,
    PRIMARY KEY (role_id, permission_id),
    FOREIGN KEY (role_id) REFERENCES roles(id),
    FOREIGN KEY (permission_id) REFERENCES permissions(id)
);

第五层:资源层(可选,用于更细粒度控制)

CREATE TABLE resources (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    resource_name VARCHAR(50) UNIQUE NOT NULL,
    resource_type VARCHAR(50) NOT NULL,
    parent_id BIGINT,
    url VARCHAR(255),
    status TINYINT NOT NULL DEFAULT 1,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (parent_id) REFERENCES resources(id)
);
 
-- 权限-资源关联表
CREATE TABLE permission_resources (
    permission_id BIGINT NOT NULL,
    resource_id BIGINT NOT NULL,
    actions VARCHAR(100) NOT NULL, -- 如: "create,read,update,delete"
    PRIMARY KEY (permission_id, resource_id),
    FOREIGN KEY (permission_id) REFERENCES permissions(id),
    FOREIGN KEY (resource_id) REFERENCES resources(id)
);

6. 实现流程示例

以下是一个典型的认证授权流程:

  1. 用户登录,验证用户名密码
  2. 验证成功后,生成 Access Token 和 Refresh Token
  3. 将两个 Token 返回给客户端
  4. 客户端在请求头中携带 Access Token
  5. 服务端验证 Access Token 有效性
  6. 若 Access Token 过期,客户端使用 Refresh Token 请求新的 Access Token
  7. 服务端验证 Refresh Token,生成新的 Access Token 和 Refresh Token
  8. 服务端根据 Token 中的角色信息,结合 RBAC 权限控制进行访问控制

7. 安全增强建议

  1. Refresh Token 存储安全

    • 考虑将 Refresh Token 存储在 HttpOnly Cookie 中,防止 XSS 攻击
    • 对 Refresh Token 实现严格的同源策略
  2. Token 泄露防护

    • 实现 Token 撤销机制
    • 为每个用户维护一个唯一的设备标识
    • 实现异常登录检测和通知
  3. 权限设计最佳实践

    • 遵循最小权限原则
    • 定期审查和清理过时角色和权限
    • 实现权限继承和权限组

到此这篇关于Java实现JWT 双签发认证+RBAC权限的示例代码的文章就介绍到这了,更多相关Java JWT 双签发认证+RBAC权限内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • Java分形绘制山脉模型

    Java分形绘制山脉模型

    这篇文章主要为大家详细介绍了Java分形绘制山脉模型,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • springboot实现token验证登陆状态的示例代码

    springboot实现token验证登陆状态的示例代码

    本文主要介绍了spring boot 实现token验证登陆状态,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • java读取某个文件夹下的所有文件实例代码

    java读取某个文件夹下的所有文件实例代码

    这篇文章主要介绍了java读取某个文件夹下的所有文件实例代码的相关资料,需要的朋友可以参考下
    2017-03-03
  • Java SpringBoot 使用拦截器作为权限控制的实现方法

    Java SpringBoot 使用拦截器作为权限控制的实现方法

    这篇文章主要介绍了Java SpringBoot 使用拦截器作为权限控制的实现,文中通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • Java应用注册成Windows服务实现自启的教程详解

    Java应用注册成Windows服务实现自启的教程详解

    这篇文章主要给大家介绍了Java应用注册成Windows服务实现自启的教程,文中有详细的代码示例和图文讲解供大家参考,具有一定的参考价值,需要的朋友可以参考下
    2024-02-02
  • java实现转圈打印矩阵算法

    java实现转圈打印矩阵算法

    这篇文章主要为大家详细介绍了java实现转圈打印矩阵算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • SpringMVC异常全局捕获与错误响应的处理方法

    SpringMVC异常全局捕获与错误响应的处理方法

    编程式异常处理是通过在代码中 显式编写异常捕获逻辑(如 try-catch 块)来管理异常的方式,开发者需要手动处理每一个可能抛出异常的代码段,本文给大家介绍SpringMVC异常全局捕获与错误响应的处理方法,感兴趣的朋友一起看看吧
    2025-03-03
  • 浅谈Spring Cloud zuul http请求转发原理

    浅谈Spring Cloud zuul http请求转发原理

    这篇文章主要介绍了浅谈Spring Cloud zuul http请求转发原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 使用VS Code进行java开发与调试的图文教程

    使用VS Code进行java开发与调试的图文教程

    这篇文章主要介绍了如何在计算机上安装JDK、VSCode以及Java扩展包,并详细说明了配置Java运行环境的过程,还展示了如何在VSCode中新建一个Java项目,需要的朋友可以参考下
    2025-02-02
  • springboot3.x版本集成log4j冲突以及解决log4j冲突不生效问题

    springboot3.x版本集成log4j冲突以及解决log4j冲突不生效问题

    由于Spring Boot自带的Logback与Log4j冲突,去除了Logback的jar包后仍存在,原因是其他包也引入了Logback,解决方法是找到并去除引入Logback的其他包,如actuator包,并更新Maven
    2024-11-11

最新评论