当前位置 博文首页 > zhtbs的博客:Springboot 入门培训 10 Security(二) 数据库DB

    zhtbs的博客:Springboot 入门培训 10 Security(二) 数据库DB

    作者:[db:作者] 时间:2021-09-14 19:41

    介绍Security中的自定义验证方法,继承UserDetailsService接口在实现类中连接数据库DB进行登录验证业务。

    验证与授权

    ? 在上一章中我们学到了在「WebSecurityConfigurerAdapter」的子类中的如何定义验证与授权,来完成用户名称与密码的登录验证与授权功能。

    • 验证方法 protected void configure(AuthenticationManagerBuilder auth)

    • 授权方法 protected void configure(HttpSecurity http)
      可以查看上一篇
      Springboot+Security 入门培训 9 Security 登录过滤器 初始化
      验证方法

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      PasswordEncoder encoder = 
      PasswordEncoderFactories.createDelegatingPasswordEncoder();
      auth.inMemoryAuthentication()
      .withUser("zht").
      password(encoder.encode("123456")).roles("USER")
      .and()
      .withUser("admin").
      password(encoder.encode("123456")).roles("ADMIN");  
    }
    

    设置用户名称zht密码123456为普通用户, 用户名称admint密码123456为普管理员用户。这样在登录页面中可以录入上面的用户名称与密码来验证成功,验证成功后可以直接获得对应的用户权限的授权内容。在通过这些授权内容获得有权限访问的url路径内容。

    授权方法

    protected void configure(HttpSecurity http) throws Exception { 
      http.authorizeRequests()
          .antMatchers("/zht/temp1").permitAll()
          .antMatchers("/zht").hasRole("USER")
          .antMatchers("/admin").hasRole("ADMIN")
          .anyRequest().authenticated()
          .and().formLogin()
          .and()
          .logout().logoutSuccessUrl("/logout").permitAll()
          .and().httpBasic();
    }
    

    这样设置只用设置几个用户,演示还可以但是在正式开发中就不行了。在开发中我们会把用户信息保存在数据库的表中,我们需要动态的来获得用户信息内容。

    1 用户验证接口 UserDetailsService

    使用UserDetailsService接口来自定义自己的信息验证服务。在实现类中重写loadUserByUsername方法来完成用户名称与密码验证的过程,在返回UserDetails类对象。

    UserDetailsService接口

    package org.springframework.security.core.userdetails;
    public interface UserDetailsService {
        UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
    }
    

    UserDetailsService接口实security包中自己定义的接口不需要我们来创建。我们直接继承使用就可以了。

    ZhtDetailsServiceImpl类

    @Component
    public class ZhtDetailsServiceImpl 
        implements UserDetailsService {
        //用户验证方法
        public UserDetails loadUserByUsername(String username) 
            throws UsernameNotFoundException {
            //用户登录名称验证
            if (username == null) {
                throw new UsernameNotFoundException("用户名称有错误 : " + username);
            }
            //密码转换器生成
            PasswordEncoder 
                encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
            String password = encoder.encode("123456");
            //security权限设置 ADMIN  USER  
            Collection<GrantedAuthority> authorities = new ArrayList();
            authorities.add(new SimpleGrantedAuthority("ADMIN"));
            //验证成功信息设置
            User user = new User(username, password, authorities);
            return user;
        }
    }
    

    创建一个验证实现类,继承org.springframework.security.core.userdetails.UserDetailsService接口,在覆盖loadUserByUsername方法写验证过程。

    • ? User user = new User(username, password, authorities); 在User 类中定义动态验证器。

      与前端页面获得到的用户名称,密码进行验证。

    前端登录页面用户可以录入任何用户名称,密码一定是123456就可以登录成功。

    WebSecurityConfigurerAdapter子类中configure**(**AuthenticationManagerBuilder auth)设置自定义用户验证信息服务。

    @Autowired
    UserDetailsService service;
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        //自定义用户验证信息服务
        auth.userDetailsService(service);
    }
    

    WebSecurityConfig类

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    //这里设置认证与授权信息内容
    //用户名与密码验证
    //AuthenticationManagerBuilder auth 验证方法
    @Autowired
    UserDetailsService service;
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        //自定义用户验证信息服务
        auth.userDetailsService(service);
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests().
          antMatchers("/zht/temp1").permitAll()
          .anyRequest()
          .authenticated()
          .and().formLogin()
          .and().httpBasic();
      }
    }
    

    浏览器中http://localhost:9089/login ,在用户名称随便录入用户名称,密码必须是123456.

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QqWclqwH-1631263950148)(D:\开发工具\开发学习文档typea\su0222.png)]

    登录成功后看到的页面

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BmAU9lTs-1631263950152)(D:\开发工具\开发学习文档typea\su00333.png)]

    2 自定义数据库连接验证信息服务

    本文介绍如何使用数据库中的数据来验证登录信息内容。

    创建一个简单的用户登录验证信息表。

    CREATE TABLE sys_zht (
      name VARCHAR(100) NOT NULL,
      pawd VARCHAR(100) NOT NULL,
      role VARCHAR(100) NOT NULL,
      CONSTRAINT account_pk PRIMARY KEY (name)
    );
    insert into sys_zht values('zht','123456','ADMIN');
    insert into sys_zht values('user','123456','USER');
    

    对数据库的操作不熟悉的可以参考我们的。
    Springboot + MyBatis 培训入门系列

    xml查询sql

    <mapper namespace="cn.core.my.app.Controller.UserDao">
        <select id="findUser" resultType="map">
         select * from sys_zht where name=#{username}
        </select> 
    </mapper>
    
    • 创建用户查询登录sql文信息内容

    UserDao接口

    @Mapper
    public interface UserDao {
        public List<Map> findUser(Map map);
    }
    
    • 定义 spring MyBatis 用户登录查询接口,创建查询方法List findUser(Map map)。

    登录验证业务

    @Component
    public class ZhtDetailsServiceImpl implements UserDetailsService {
        @Autowired
        UserDao dao;
        public UserDetails loadUserByUsername(String username) 
      throws UsernameNotFoundException {
        //查询数据库获得用户登录信息
        Map par=new HashMap();
        par.put("username",username);
        List list=dao.findUser(par);
        //没有查询出用户信息
        if(list.isEmpty()){
            throw new UsernameNotFoundException("用户名称有错误 : " + username);
        }
        Map up=(Map)list.get(0);
        //密码转换器生成
        PasswordEncoder
          encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        String password = encoder.encode((String) up.get("pawd"));
        //security权限设置 ADMIN  USER
        Collection<GrantedAuthority> authorities = new ArrayList();
        authorities.add(new SimpleGrantedAuthority((String)up.get("role")));
        //验证成功信息设置
         User user = new User((String)up.get("name"),password, authorities);