SpringSecurity如何使用UserDetails接口
UserDetail接口提供一些方法:
public interface UserDetails extends Serializable { Collection<? extends GrantedAuthority> getAuthorities(); String getPassword(); String getUsername(); boolean isAccountNonExpired(); boolean isAccountNonLocked(); boolean isCredentialsNonExpired(); boolean isEnabled(); }
提供查询用户进行身份验证的用户名,密码,授予用户的权限。
开发者可以在UserDetail的实现类增加自定义在持久层的用户对象User,重写接口的查询方法。
@Data @NoArgsConstructor @AllArgsConstructor public class LoginUser implements UserDetails{ private User user; @Override public Collection<? extends GrantedAuthority> getAuthorities() { return null; } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getUsername(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
UserDetailService接口提供抽象方法loadUserByUserName获取UserDetail,方法体内部具体返回开发者自定义的UserDetail。
@Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserDao userDao; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //查询用户信息 LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(User::getUsername,username); User user = userDao.selectOne(queryWrapper); //如果没有查到用户,抛出异常 if (Objects.isNull(user)){ throw new ServiceException(ResultCode.UNAUTHORIZED); } //查询用户角色信息 return new LoginUser(user); } }
接下来就是使用UserDetail的应用场景了
开发者调用AuthenticationManager. authenticate(authentication) 返回一个完整的Authentication对象,此功能验证了用户身份.
此方法调用的方法链路是
ProviderManager(实现AuthenticationManager接口).authenticate()->AbstractUserDetailsAuthenticationProvider().authenticate(authentication)->DaoAuthenticationProvider.retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)->CachingUserDetailsService.loadUserByUsername()->UserDetailsServiceDelegator.loadUserByUsername()->UserDetailService.loadUserByUserName()->UserDetailServiceImpl.loadUserByUserName()
开发者使用时注入AuthenticationManager对象并调用authenticate。
@Resource private AuthenticationManager authenticationManage
//进行用户认证 UserAppTokenAuthenticationToken authenticationToken = new UserAppTokenAuthenticationToken(userList.get(0).getAppKey(), userService); Authentication authenticate = authenticationManager.authenticate(authenticationToken);
token的身份验证流程:
浏览器发送用户名和密码给服务器,服务器生成数字签名加密后得到token 返回浏览器,请求API时携带token,解密后进行签名认证,判断
有效性,然后返回数据。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理