1.让我们自己的UserService接口继承UserDetailsService;也可以在用户的实体类中实现UserDetails接口,重写对应的方法,角色实体类也要实现GrantedAuthority接口,重写对应的方法,这样User的业务层操作就会变得非常简单,因为用户和角色实体类已经满足了springSecurity的规范,不需要在业务层中转换了,具体操作参考springboot整合springSecurity https://www.cnblogs.com/roadlandscape/p/12487086.html
public interface UserService extends UserDetailsService { public void save(SysUser user); }
2.到实现类实现 loadUserByUsername 方法,编写对应的逻辑
@Service("userService") @Transactional public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; // 需要注入加密对象 @Autowired private BCryptPasswordEncoder passwordEncoder; @Override public void save(SysUser user) { // 保存用户时密码加密保存 user.setPassword(passwordEncoder.encode(user.getPassword())); userDao.save(user); } /** * 认证业务 * @param username 用户在浏览器输入的用户名 * @return UserDetails 是springSecurity自己的用户对象 * @throws UsernameNotFoundException */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { try { // 根据用户名做查询 SysUser user = userDao.findByName(username); if (user == null) { //若用户名不对,直接返回null,表示认证失败。 return null; } // 设置用户的角色,用户的权限是根据角色决定的 List<SimpleGrantedAuthority> authorities = new ArrayList<>(); List<SysRole> roles = user.getRoles(); for (SysRole role : roles) { authorities.add(new SimpleGrantedAuthority(role.getRoleName())); } //最终需要返回一个SpringSecurity的UserDetails对象,{noop}表示不加密认证。 // UserDetails userDetails = new User(user.getUsername(), "{noop}" + user.getPassword(), authorities); UserDetails userDetails = new User(user.getUsername(), user.getPassword(), authorities); return userDetails; } catch (Exception e) { e.printStackTrace(); // springSecurity内部认为返回null就是认证失败 return null; } } }
3.在SpringSecurity主配置文件中指定认证使用的业务对象
<!-- 把加密对象放入IOC容器中 --> <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> <!-- 设置Spring Security认证用户信息的来源 --> <security:authentication-manager> <security:authentication-provider user-service-ref="userService"> <!--<security:user-service> <security:user name="user" password="{noop}user" authorities="ROLE_USER"/> <security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/> </security:user-service>--> <!-- 指定认证使用的加密对象 --> <security:password-encoder ref="passwordEncoder"/> </security:authentication-provider> </security:authentication-manager>
4.编写一个测试类,生成一串加密后的字符串,存入数据库,然后验证登录操作
public class EncodingTest { //加盐加密 //123---bcaddjlj 加盐 321xiaoming---dsgagagfd //动态加盐 //https://bbs.pediy.com/thread-205481.htm public static void main(String[] args) { BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); System.out.println(passwordEncoder.encode("aaa")); } }
验证登录.........