You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

微服务中如何通过JWT实现user-service与hospital-service的权限联动?

微服务权限联动方案:user-service与hospital-service的协作实现

核心协作逻辑

基于JWT令牌的无状态身份传递是两个服务联动的核心:user-service负责签发包含用户身份、角色信息的JWT,hospital-service通过验证令牌合法性,解析出用户角色,进而完成权限校验。全程不需要跨服务频繁调用user-service,保证性能的同时实现解耦。

具体实现步骤

1. 客户端传递JWT令牌

用户在user-service完成登录后,获取到访问令牌(Access Token)。后续请求hospital-service的业务接口时,需在HTTP请求头中携带该令牌,格式为:

Authorization: Bearer <JWT_TOKEN>

2. hospital-service本地验证JWT合法性

hospital-service与user-service共享JWT签名密钥(比如对称加密的密钥,或非对称加密的公钥),直接在本地完成令牌验证:

  • 验证令牌的签名是否有效,防止篡改
  • 检查令牌是否过期
  • 验证令牌的签发方(issuer)是否为可信的user-service

注:如果不想共享密钥,也可以调用user-service提供的令牌验证接口(比如/api/auth/validate-token),但会增加跨服务调用开销,适合对密钥共享敏感的场景。

3. 解析用户身份并注入SecurityContext

验证通过后,解析JWT的Payload部分,提取关键信息:用户ID、角色列表(比如["RECEPTIONIST"]或["DOCTOR"]),然后将这些信息封装成用户认证对象,存入hospital-service的SecurityContext中,和user-service的授权逻辑保持一致。

4. 接口层权限校验

在hospital-service的业务接口上,通过权限注解或拦截器实现角色校验:

  • 粗粒度权限:用Spring Security的@PreAuthorize注解直接限制角色,比如添加医生的接口:
    @PostMapping("/doctors")
    @PreAuthorize("hasRole('RECEPTIONIST')")
    public ResponseEntity<Void> addDoctor(@RequestBody DoctorDTO doctor) {
        // 业务逻辑
    }
    
  • 细粒度数据权限:比如医生只能查看自己负责的患者,可在业务逻辑中从SecurityContext获取当前用户ID,过滤数据库查询条件:
    @GetMapping("/patients")
    @PreAuthorize("hasRole('DOCTOR')")
    public ResponseEntity<List<PatientDTO>> getMyPatients() {
        Long currentDoctorId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().getId();
        return patientRepository.findByDoctorId(currentDoctorId);
    }
    

特殊场景处理

  • 角色变更:因为JWT是无状态的,一旦签发无法修改。如果user-service调整了用户角色,需让旧令牌失效(比如通过令牌黑名单),或等待令牌自然过期,用户重新登录获取包含新角色的令牌。
  • 刷新令牌:客户端用刷新令牌向user-service获取新的访问令牌,hospital-service只需验证新令牌即可,无需感知刷新逻辑。

内容的提问来源于stack exchange,提问作者dsa14dfS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 08:07:17