SpringSecurity使用数据库数据完成认证
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")); } }
验证登录.........

浙公网安备 33010602011771号