Authentication:身份凭证



Authentication 是 Spring Security 的核心接口,代表当前请求者的身份信息。
1 2 3 4 5 6 7 8
| public interface Authentication extends Principal, Serializable { Collection<? extends GrantedAuthority> getAuthorities(); Object getCredentials(); Object getDetails(); Object getPrincipal(); boolean isAuthenticated(); void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException; }
|
最常用的实现是 UsernamePasswordAuthenticationToken:
1 2 3 4 5 6 7 8 9 10 11 12
| UsernamePasswordAuthenticationToken unauthenticated = new UsernamePasswordAuthenticationToken("admin", null);
UsernamePasswordAuthenticationToken authenticated = new UsernamePasswordAuthenticationToken( "admin", "password", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN") ); authenticated.setAuthenticated(true);
|
GrantedAuthority:权限标识
GrantedAuthority 代表一个权限或角色。最常见的实现是 SimpleGrantedAuthority:
1 2 3
| GrantedAuthority roleAdmin = new SimpleGrantedAuthority("ROLE_ADMIN"); GrantedAuthority roleUser = new SimpleGrantedAuthority("ROLE_USER"); GrantedAuthority permissionRead = new SimpleGrantedAuthority("USER_READ");
|
注意:ROLE_ 前缀是约定俗成的,不是强制的。但 hasRole() 方法会自动添加这个前缀,所以建议使用这个约定。
SecurityContext:安全上下文
SecurityContext 持有当前请求的 Authentication 对象:
1 2 3 4
| public interface SecurityContext extends Serializable { Authentication getAuthentication(); void setAuthentication(Authentication authentication); }
|
SecurityContextHolder:上下文持有者
SecurityContextHolder 通过 ThreadLocal 存储 SecurityContext,确保每个线程有独立的安全上下文:
1 2 3 4 5 6 7 8
| Authentication auth = SecurityContextHolder.getContext().getAuthentication();
SecurityContextHolder.getContext().setAuthentication(authenticated);
SecurityContextHolder.clearContext();
|
注意:ThreadLocal 在异步场景下可能失效。Spring Security 5.4+ 提供了 SecurityContextRepository 支持异步场景。
四者的协作关系
1 2 3 4 5 6
| SecurityContextHolder (ThreadLocal) └── SecurityContext └── Authentication ├── Principal (用户名等标识信息) ├── Credentials (密码等凭据) └── Collection<GrantedAuthority> (权限列表)
|
这个设计的关键优势是:认证信息一旦设置,整个请求处理链中的任何组件都可以访问它,无需逐层传递。