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

Java中UsernamePasswordAuthenticationToken使用及代码解析

解析UsernamePasswordAuthenticationToken的这段代码实现

先看你给出的代码:

UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
    userDetails, null,
    userDetails == null ?
        List.of() : userDetails.getAuthorities()
);

这段代码的核心是构造一个已完成认证的Spring Security Authentication对象,下面逐个拆解你关心的点:

1. userDetails参数的作用

userDetails是Spring Security用来封装用户核心信息的标准对象,里面包含了用户名、加密后的密码、用户权限、账号状态(是否锁定、过期、禁用等)。这里把它作为Authentication的principal(主体)传入,后续这个对象会被存入SecurityContextHolder,业务代码里可以通过SecurityContextHolder.getContext().getAuthentication().getPrincipal()获取当前登录用户的完整信息。

2. 传入null作为凭证(credentials)的原因

这里的credentials指的是用户的登录凭证(通常是密码)。传入null是Spring Security的标准实践:

  • 认证完成后,密码已经完成了校验使命,继续保留会有敏感信息泄露的风险(比如被序列化、日志打印)。
  • 已认证的Authentication对象不需要再携带凭证,Spring Security内部会通过isAuthenticated()状态来判断认证状态,而非凭证是否存在。

3. 权限设置的逻辑

这个三元表达式是典型的空安全处理,目的是保证Authentication对象始终持有合法的权限集合:

  • 当userDetails为null时(比如认证失败、用户不存在的极端场景),用List.of()生成一个空的不可变权限列表,避免因为权限集合为null导致后续权限校验时抛出空指针异常。
  • 当userDetails有效时,调用userDetails.getAuthorities()获取用户的权限集合(比如ROLE_ADMIN、ROLE_USER这类GrantedAuthority实例),这些权限会用于后续的接口访问控制、方法级权限校验(比如@PreAuthorize注解)。
  • 使用List.of()是因为它返回的是不可变列表,能防止后续代码意外修改权限集合,保证权限信息的安全性和稳定性。

补充说明

这段代码一般出现在认证成功后的流程里:比如用户名密码校验通过后,用查询到的userDetails构造已认证的Authentication对象,再存入SecurityContextHolder,这样后续的请求就能自动识别当前用户的身份和权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:23:13