You need to enable JavaScript to run this app. 如何使用自定义令牌系统保护Java Spring Boot API并实现用户权限管控
优惠活动
大模型
产品
解决方案
定价
更多

如何使用自定义令牌系统保护Java Spring Boot API并实现用户权限管控

基于自建自定义令牌的Spring Boot API权限控制实现方案

整套方案完全适配自定义令牌体系,不需要依赖JWT等标准令牌格式,可直接复用自建令牌的存储、校验逻辑,实现令牌权限识别与Controller层的Admin访问控制。

一、自定义令牌认证过滤器:打通令牌校验到权限装载的链路

复用Spring Security的过滤器链路,避免手写重复的拦截逻辑:

  • 继承OncePerRequestFilter,确保单个请求周期内只执行一次令牌解析逻辑
  • 从请求头(通常为Authorization: Bearer <自定义令牌值>)提取携带的令牌字符串
  • 调用自建的令牌校验服务:完成令牌有效性校验,同时拉取令牌绑定的权限类型(比如是Admin/普通User)
  • 将校验通过的权限列表转换为Spring Security可识别的权限对象,存入SecurityContextHolder,供后续接口层的权限校验环节使用
  • 令牌无效、过期的请求直接返回401未认证响应,不进入后续业务流程

核心实现代码参考:

public class CustomTokenAuthFilter extends OncePerRequestFilter {
    @Autowired
    private CustomTokenService customTokenService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                    HttpServletResponse response, 
                                    FilterChain filterChain) throws ServletException, IOException {
        // 提取请求中的自定义令牌
        String token = request.getHeader("Authorization");
        // 调用自建服务校验令牌并获取关联权限
        TokenInfo tokenInfo = customTokenService.validateAndGetInfo(token);
        if (tokenInfo == null) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }
        // 转换为Spring Security标准权限列表,适配角色校验规则
        List<GrantedAuthority> authorities = tokenInfo.getPermissionTypes()
                .stream()
                .map(perm -> new SimpleGrantedAuthority("ROLE_" + perm))
                .collect(Collectors.toList());
        // 构建认证上下文,供后续权限校验使用
        Authentication auth = new UsernamePasswordAuthenticationToken(
                tokenInfo.getSubjectId, null, authorities
        );
        SecurityContextHolder.getContext().setAuthentication(auth);
        filterChain.doFilter(request, response);
    }
}

二、Spring Security基础链路配置

  • 适配API场景:关闭表单登录、CSRF跨域校验,适配无状态的接口调用模式
  • 指定自定义过滤器的执行顺序:将自定义令牌过滤器放在默认的用户名密码校验过滤器之前执行
  • 配置基础路径拦截规则:将令牌获取、公开访问的接口设置为匿名可访问,其余所有接口默认要求完成认证才能访问

基础配置代码参考:

@Configuration
@EnableMethodSecurity // Spring Security 6.x+ 开启方法级权限校验的注解,老版本替换为@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(AbstractHttpConfigurer::disable)
            .formLogin(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/auth/token").permitAll() // 放开令牌获取接口
                .anyRequest().authenticated() // 其余接口默认要求认证
            )
            .addFilterBefore(customTokenAuthFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}

三、Controller层的Admin权限访问控制

完全通过注解实现细粒度控制,不需要在业务方法内手写权限判断逻辑:

  • 如果单个接口需要仅Admin可访问,在对应方法上加@PreAuthorize("hasRole('ADMIN')")注解,框架会自动校验当前请求对应的权限列表,只有携带Admin权限的令牌才能调用成功,权限不足时直接返回403响应
  • 如果整个Controller类下的所有接口都仅对Admin开放,直接在类上加上述权限注解,类内所有方法都会自动继承该校验规则

示例代码:

@RestController
@RequestMapping("/api/admin")
public class AdminController {
    // 仅Admin权限的令牌可调用该删除用户接口
    @PreAuthorize("hasRole('ADMIN')")
    @DeleteMapping("/user/{id}")
    public Result deleteUser(@PathVariable Long userId) {
        // 具体业务逻辑
        return Result.success();
    }
}

实现注意事项

  • 权限命名需适配Spring Security的校验规则:角色类权限统一加ROLE_前缀,避免hasRole注解匹配失效
  • 不要将权限类型明文存在自定义令牌的可篡改字段中,必须在服务端完成令牌有效性校验后,再从服务端存储(数据库/Redis)拉取令牌绑定的权限,防止令牌被篡改后伪造Admin权限
  • 令牌权限变更、过期、注销时,要同步清除服务端存储的对应权限数据,避免旧令牌残留的权限造成安全风险
  • 不需要在每个接口中手动编写if (userType.equals("ADMIN"))这类判断逻辑,完全复用Security上下文的权限校验能力,减少代码冗余

内容的提问来源于stack exchange,提问作者matthias-schneglberger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 09:15:06