zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Android游戏开发22:Android动画的实现J2me游戏类库用于Android开发
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第三部分,完整代码)
    使用OGR创建dxf格式矢量数据
    mysql 数据库引擎 MyISAM InnoDB 大比拼 区别
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第二部分)
    mysql 更改数据库引擎
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第一部分)
    android 数字键盘使用
    MySQL Innodb数据库性能实践
    eclipse : Error while performing database login with the driver null
  • 原文地址:https://www.cnblogs.com/yscec/p/14233244.html
Copyright © 2011-2022 走看看