• SpringSecurity(四): 动态认证用户信息UserDetailsService


    SpringSecurity(一、二、三)身份认证的用户名和密码是启动服务器自动生成的,或者是代码中写死的,存储在内存中。而实际项目中应该从动态的从数据库中获取进行身份认证。
     
    1.实现流程:  
      (1)关注 UserDetailsService 、 UserDetails 接口
      (2)自定义一个 UserDetailsService 接口的实现类 CustomUserDetailsService ,实现该接口中的loadUserByUsername 方法 ,通过该方法定义获取用户信息的逻辑。
      (3)从数据库获取到的用户信息封装到 UserDetail 接口的实现类中(Spring Security 提供了一个org.springframework.security.core.userdetails.User 实现类封装用户信息)。
      (4)如果未获取到用户信息,则抛出异常 throws UsernameNotFoundException
    public interface UserDetails extends Serializable { 
      //此用户可访问的资源权限
      Collection<? extends GrantedAuthority> getAuthorities();
      //用户名
      String getPassword();
      //密码
      String getUsername();
      //帐户是否过期(true 未过期,false 已过期)   boolean isAccountNonExpired();
      //帐户是否被锁定(true 未锁定,false 已锁定),锁定的用户是可以恢复的   boolean isAccountNonLocked();
      //密码是否过期(安全级别比较高的系统,如30天要求更改密码,true 未过期,false 过期)   boolean isCredentialsNonExpired();
      //帐户是否可用(一般指定是否删除,系统一般不会真正的删除用户信息,而是假删除,通过一个状态码标志 用户被删除)删除的用户是可以恢复的   
    boolean isEnabled();
    }

    2.自定义CustomUserDetailsService类实现UserDetailsService接口

    /**
     * 查询数据库中的用户信息
     */
    @Component("CustomUserDetailsService")
    public class CustomUserDetailsService implements UserDetailsService {
       Logger logger=LoggerFactory.getLogger(CustomUserDetailsService.class);
    
       @Autowired
        BCryptPasswordEncoder bCryptPasswordEncoder;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
           logger.info("请求认证的用户名:"+username);
    
           //1.通过请求的用户名去数据库中查询用户信息
            if (!"zcc".equals(username)){
                throw new UsernameNotFoundException("用户名或密码错误");
            }
    
            //假设当前这个用户在数据库中存储的密码是123
            String password=bCryptPasswordEncoder.encode("123");
    
            //2.查询该用户所拥有的权限
            
    
            // 3.封装用户信息: username用户名,password数据库中的密码,authorities资源权限标识符
            // SpringSecurity 底层会校验是否身份合法。
            return  new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("ADMIN"));
    
        }
    }

    3.重构安全配置类SpringSecurityConfig

      注入 CustomUserDetailsService  在confifigure(AuthenticationManagerBuilder auth) 方法中指定认证方式
       @Autowired
        CustomUserDetailsService customUserDetailsService;
    
    
        /**
         * 认证管理器:
         * 1、认证信息提供方式(用户名、密码、当前用户的资源权限)
         * 2、可采用内存存储方式,也可能采用数据库方式等
         *
         * @param auth
         * @throws Exception
         */
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            //基于内存存储认证信息 存储的密码必须是加密后的 不然会报错:There is no PasswordEncoder mapped for the id "null"
            //auth.inMemoryAuthentication().withUser("zcc").password("123").authorities("ADMIN");
            /*String password = bCryptPasswordEncoder().encode("123");
            logger.info("加密后的密码:" + password);
            auth.inMemoryAuthentication().withUser("zcc").password(password).authorities("ADMIN");*/
    
    
            // 指定使用自定义查询用户信息来完成身份认证
            auth.userDetailsService(customUserDetailsService);
    
        }

     完整代码地址:https://gitee.com/zhechaochao/security-parent.git

  • 相关阅读:
    基于WebGIS的电子政务应用(基于J2EE的MVC架构)
    和菜鸟一起学c之函数中堆栈及运行内存情况
    《父亲》献给程序员的我们
    黑客高级技巧之Linux后门技术及实践
    批处理实现对网站的监测
    无敌批处理
    Adsutil.vbs在脚本入侵中的妙用
    黑客高级技巧之Linux后门技术及实践
    ms 06014漏洞检测代码
    ms 06014漏洞检测代码
  • 原文地址:https://www.cnblogs.com/yscec/p/14233244.html
Copyright © 2020-2023  润新知