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"));
    }
}

  验证登录.........

原文地址:https://www.cnblogs.com/roadlandscape/p/12482260.html