• Spring Security集成异常总结


      背景:本来有一个web系统,使用的是Spring Security,有自己的用户表。现在给的需求是集成另一个内部系统,在系统间实现免密登录跳转。继承的过程一切从简,对方直接把用户表给我了,使用多数据源操作,同时读2个用户表。

      读多数据源我参考的是这篇文章:https://wangsong.blog.csdn.net/article/details/107330001

        @Bean
        @Primary
        public UserDetailsService userDetailsService1() {
            return new UserDetails1ServiceImpl(sysUserService, dataService);
        }
    
        @Bean
        public UserDetailsService userDetailsService2() {
            return new UserDetails2ServiceImpl(userInfoService);
        }
    
        /**
         * 手动创建AuthenticationManager,可以声明2个以上的UserDetailsService
         * 默认先用@Primary注解的bean查询用户,没查到在去第二个bean查询用户
         *
         * @return AuthenticationManager
         * @throws Exception /
         */
        @Bean
        protected AuthenticationManager authenticationManager() throws Exception {
            // 用户表1
            DaoAuthenticationProvider dao1 = new DaoAuthenticationProvider();
            dao1.setUserDetailsService(userDetailsService1());
            dao1.setPasswordEncoder(passwordEncoder());
            // 用户表2
            DaoAuthenticationProvider dao2 = new DaoAuthenticationProvider();
            dao2.setUserDetailsService(userDetailsService2());
            dao2.setPasswordEncoder(passwordEncoder());
    
            List<AuthenticationProvider> providers = new ArrayList<>();
            providers.add(dao1);
            providers.add(dao2);
            return new ProviderManager(providers);
        }

      有2个service实现了2个UserDetailsService接口,每个service读取一张用户表。并且同时注册给AuthenticationManager,在需要查询用户时,优先查询@Primary注解的Service,没有在查第二个service。

      好了,我们继续吐槽... 我接入的内部系统的用户表密码居然是明文存储的,使用原来的login方法各种报错,我只能再复制一份login方法,开始改造,登录入口虽然不一样,但登录功能后的逻辑全是一样的。改造过程中出现的异常主要有2面两个:

      1. Encoded password does not look like BCrypt

      错误原因:原系统都是BCryptPasswordEncoder加密的密码,前端传的是加密串,数据库存的也是加密串。而我介入的内部系统全是未加密的字符串,所以就报这样的错误。

      解决办法:我把用户表2的数据查询出来之后,把密码进行了加密,用户调动login方法的密码也加密了。接下来又报了下面的错误。

      2. Bad credentials 

      这个错误肯定是凭证错误,可以理解为用户名或密码错误。我们初步判断是密码机加密到那个步骤出错了。后来翻阅资料发现原来是我多做了一步。看下面测试。

        @Autowired
        private PasswordEncoder passwordEncoder;
    
        @Test
        public void checkPassword(){
            // 用户输入的登录密码,未加密
            String password1 = "123456";
            // 数据库里存的密码,加密字符串
            String password2 = passwordEncoder.encode("123456");
            if (!passwordEncoder.matches(password1, password2)) {
                System.out.println("密码错误");
            } else {
                System.out.println("验证通过");
            }
        }

      这个测试说明,用户登录时密码是不需要加密的。我回看原来的login方法,发现也是拿到密文密码再解密后使用的。好吧,我多此一举了,把登录密码直接使用后,登录正常了。

  • 相关阅读:
    初识Node
    从服务器获取信息的方式
    引用对象的指针传递
    使用定时器来控制一次执行的任务数量
    JS字符串拼接的方法及性能比较
    提升JS比较效率的方式
    DOM访问优化
    JS数据存取效率的优化
    JS脚本加载顺序及优化
    python 基本用法
  • 原文地址:https://www.cnblogs.com/huanshilang/p/13589544.html
Copyright © 2020-2023  润新知