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,解密后进行签名认证,判断
有效性,然后返回数据。

浙公网安备 33010602011771号