MST
星途 面试题库

面试题:安全认证之JWT在复杂权限场景下的应用

在一个具有多种角色和细粒度权限控制的系统中,使用JWT进行权限管理。假设存在管理员、普通用户和访客三种角色,普通用户又分为不同的小组,各有不同权限。请说明如何设计JWT的Payload部分,以满足这种复杂的权限管理需求,并阐述在服务端如何基于JWT进行高效的权限验证。
17.0万 热度难度
后端开发安全认证

知识考点

AI 面试

面试题答案

一键面试

JWT Payload设计

  1. 通用信息
    • sub(subject):标识用户的唯一标识符,例如用户ID。
    • role:用户角色,取值为admin(管理员)、user(普通用户)、guest(访客)。
  2. 普通用户额外信息(针对不同小组权限)
    • roleuser时,添加group字段,标识用户所属小组。例如group: "group1"
    • 同时添加permissions字段,以数组形式列出该用户或小组所拥有的具体权限。例如["read_file", "write_file"]
  3. 示例Payload
    {
        "sub": "1234567890",
        "role": "user",
        "group": "group1",
        "permissions": ["read_file", "write_file"]
    }
    
    对于管理员,可以简化为:
    {
        "sub": "0987654321",
        "role": "admin",
        "permissions": ["all_permissions"]
    }
    
    对于访客:
    {
        "sub": "guest_id_1",
        "role": "guest",
        "permissions": ["view_public_content"]
    }
    

服务端权限验证

  1. 验证JWT合法性
    • 使用JWT库验证JWT的签名,确保JWT未被篡改。例如在Java中可以使用jjwt库:
    try {
        Claims claims = Jwts.parserBuilder()
               .setSigningKey(secretKey)
               .build()
               .parseClaimsJws(jwt)
               .getBody();
    } catch (JwtException e) {
        // JWT不合法,返回权限不足等错误
        return false;
    }
    
  2. 基于角色和权限的验证
    • 从解析后的Payload中获取role字段。
    • 如果roleadmin,则赋予所有权限,直接通过验证。
    • 如果roleuser,获取grouppermissions字段。根据请求的操作,检查permissions数组中是否包含对应的权限。例如,请求写文件操作,检查permissions数组中是否有write_file权限。
    • 如果roleguest,同样根据请求操作检查permissions数组,判断是否具有相应权限。
  3. 缓存优化
    • 对于频繁访问且权限相对固定的资源,可以将权限验证结果进行缓存。例如使用Redis缓存,以用户ID和资源路径作为键,权限验证结果作为值。在每次权限验证时,先检查缓存中是否已有结果,若有则直接返回,提高验证效率。