当前位置: 首页 > 科技观察

SpingSecurity-动态认证用户信息

时间:2023-03-21 18:35:16 科技观察

概述前两节我们介绍的SpringSecurity认证用户和密码是在启动服务器后自动生成,编码死或者存入内存,但是在实际项目中需要从中获取动态从数据库中获取用户信息进行身份认证。SpringSecurity提供了一个UserDetailsS??ervice的实现类JdbcUserDetailsManager来帮助我们通过JDBD的方式连接数据库和SpringSecurity。该项目已准备好添加依赖项。我们使用的数据库是mysql,查询数据的方式使用的是mybatis-plus,所以需要引入mysql驱动和mybatis-plus依赖。mysqlmysql-connector-java运行时com.baomidoumybatis-plus-boot-starter3.5.1添加我们添加的数据库配置通过依赖后,需要在application.yml中添加数据库链接,如下:spring:datasource:url:jdbc:mysql://localhost:3306/mybatis?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=false用户名:root密码:rootdriver-class-name:com.mysql.cj.jdbc.Driver这里数据库默认链接的是mybatis数据库,用户名为root,密码为root,读者可以自行修改创建用户和权限根据实际情况表:我们只是举例,所以我们只创建一个简单的用户(sys_user)和权限(sys_authorities)两张表,sql如下:DROPTABLEIFEXISTSsys_用户;创建表Esys_user(`id`BIGINT(20)NOTNULLCOMMENT'主键ID',`username`VARCHAR(30)NOTNULLCOMMENT'name',`password`VARCHAR(64)NOTNULLCOMMENT'密码',`age`INT(11)NULLDEFAULTNULLCOMMENT'age',`email`VARCHAR(50)NULLDEFAULTNULLCOMMENT'mailbox',`enabled`INT(11)notNULLDEFAULT1COMMENT'0为无效用户,1为有效用户user',`phone`VARCHAR(16)NULLDEFAULTNULLCOMMENT'电话号码',`create_time`DATETIMENULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'角色创建日期',PRIMARYKEY(id))COMMENT='用户信息表'COLLATE='utf8mb4_unicode_ci'ENGINE=InnoDB;如果存在sys_authorities则删除表;创建表`sys_authorities`(`id`INT(11)NOTNULLAUTO_INCREMENT,`user_id`INT(11)NOTNULLDEFAULT'0'COMMENT'roleauto-incrementid',`authority`VARCHAR(50)NULLDEFAULTNULLCOMMENT'authority',PRIMARYKEY(`id`))COMMENT='用户权限关系表'COLLATE='utf8mb4_unicode_ci'ENGINE=InnoDB;INSERTINTOsys_user(id,username,password,age,email,phone)VALUES(1,'admin','$2a$10$ziavqzahP2o0q6XPIEVLNOODYAdRIbJHa1v2xQwbg.6xT2y6q2lzO',18,'test1@baomidou.com',13333835911);插入sys_authorities(id,user_id,authorities)VALUES(1,1,'admin');实体类创建两个表分别对应sys_user和sys_authorities实体类sys_user实体类。@Data@TableName("sys_user")publicclassUserEntity{privateLongid;私有字符串用户名;私有字符串密码;私人整数年龄;私人字符串电子邮件;私有整数启用;privateStringphone;}sys_authorities实体类。@Data@TableName("sys_authorities")publicclassAuthoritiesEntity{privateLongid;私有字符串用户名;privateStringauthorities;}实现两个实体类的Mapper我们使用mybatis-plus来实现这两个实体类的mapper,因为这样我们(例子)可以减少代码。publicinterfaceUserMapperextendsBaseMapper{}publicinterfaceAuthoritiesMapperextendsBaseMapper{}添加@MapperScan注解添加@MapperScan("com.security.learn.mapper")注解到主入口类。@MapperScan("com.security.learn.mapper")@SpringBootApplicationpublicclassSpringSecurityLearn3Application{publicstaticvoidmain(String[]args){SpringApplication.run(SpringSecurityLearn3Application.class,args);}}UserDetailsS??ervice的实现我们需要自定义UserDetailsS??ervice接口的实现类CustomUserDetailsS??ervice,用于实现UserDetailsS??ervice接口中的loadUserByUsername方法,通过该方法定义获取用户信息的逻辑。UserDetailsS??ervice接口。CustomUserDetailsS??ervice的代码实现。@Slf4j@Service("customUserDetailsS??ervice")publicclassCustomUserDetailsS??erviceimplementsUserDetailsS??ervice{@AutowiredprivateUserMapperuserMapper;@AutowiredprivateAuthoritiesMapperauthoritiesMapper;@OverridepublicUserDetailsloadUserByUsername(Stringusername)throwsUsernameNotFoundException{log.info("认证请求:"+username);QueryWrapperwrapper=newQueryWrapper<>();wrapper.eq("用户名",用户名);ListuserEntities=userMapper.selectList(wrapper);如果(userEntities.size()>0){QueryWrapperwrapper1=newQueryWrapper<>();wrapper.eq("userId",userEntities.get(0).getId());列表authorities=authoritiesMapper.selectList(wrapper1);返回新用户(用户名,userEntities.get(0).getPassword(),AuthorityUtils.createAuthorityList(authorities.toString()));}返回空值;}}重构configure(AuthenticationManagerBuilderauth)方法重新实现configure(AuthenticationManagerBuilderauth)方法,将customUserDetailsS??ervice注入LearnSrpingSecurity类。在configure(AuthenticationManagerBuilderauth)方法中指定认证用户方法。代码实现如下:@AutowiredprivateUserDetailsS??ervicecustomUserDetailsS??ervice;/***AuthenticationManager*1.提供认证信息的方式(用户名,密码,当前用户的资源权限)*2.可以存储在内存中,也可以存储在数据库中等*@paramauth*@throwsException*/@Overrideprotectedvoidconfigure(AuthenticationManagerBuilderauth)throwsException{//super.configure(auth);//auth.inMemoryAuthentication()//.withUser("admin")//.password(passwordEncoder.encode("123456")))//.roles("admin")//.authorities("Role_admin")//.and()//.passwordEncoder(passwordEncoder);//配置BCrypt加密auth.userDetailsS??ervice(customUserDetailsS??ervice);}测试启动项目,访问http://localhost:8888/login/page。使用账号密码的结果是:账号:admin。密码:123456。