Angular+Spring Boot鉴权:后端如何获取用户信息并做权限校验?
核心原则澄清
首先纠正误区:后端可以安全解析ID Token,但绝不能将其作为授权凭证使用。ID Token的设计目的是向前端提供用户身份断言,而Access Token才是后端验证用户授权状态的合法凭证。但你完全不需要依赖前端传递的ID Token来获取用户信息,以下是合规且安全的实现方案:
具体实现步骤
前端传递Access Token到后端
前端在请求后端接口时,通过Authorization: Bearer <access_token>请求头传递Access Token,这是OAuth2/OIDC的标准做法。后端自动验证Access Token有效性
借助Spring Security OAuth2 Resource Server组件,自动完成Access Token的全维度验证(签名合法性、过期时间、受众aud匹配、发行方iss可信性等)。验证通过后,用户身份信息会被封装到OAuth2AuthenticatedPrincipal对象中供业务逻辑使用。从Access Token提取用户核心标识
多数身份提供商(如Keycloak、Auth0)会将用户唯一ID(sub字段)嵌入Access Token的声明中,后端可直接从验证后的principal中提取该值。如果需要邮箱等额外信息,可配置身份提供商将这些字段加入Access Token的自定义声明,或者通过身份提供商的用户信息端点,用有效的Access Token请求完整用户详情。查询本地数据库并校验业务权限
拿到用户ID/邮箱后,查询后端数据库获取用户角色,再执行业务逻辑校验(比如确认账单是否属于当前用户)。
记账应用场景代码示例(Spring Boot)
@RestController @RequestMapping("/bills") public class BillController { private final BillRepository billRepository; public BillController(BillRepository billRepository) { this.billRepository = billRepository; } @GetMapping("/{billId}") public ResponseEntity<Bill> getBill(@PathVariable Long billId, @AuthenticationPrincipal OAuth2AuthenticatedPrincipal principal) { // 从已验证的身份主体中提取用户唯一ID String userId = principal.getAttribute("sub"); // 查询账单并校验所有者身份 Bill targetBill = billRepository.findById(billId) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "账单不存在")); if (!targetBill.getOwnerId().equals(userId)) { throw new ResponseStatusException(HttpStatus.FORBIDDEN, "无权访问该账单"); } return ResponseEntity.ok(targetBill); } }
关键注意事项
- 禁止直接接收前端传递的ID Token并解析:ID Token的受众(
aud)是前端应用,后端并非其目标受众,直接解析不符合OIDC规范,存在安全风险。 - 配置身份提供商时,确保Access Token包含
sub等必要用户声明,减少额外的用户信息请求开销。 - 若必须使用ID Token,后端需严格验证其签名、
aud是否包含后端应用、exp过期时间等字段,但这是次选方案,优先使用Access Token+内置声明的方式。
内容的提问来源于stack exchange,提问作者robert trudel

