Sping Security-动态认证用户信息

概述

我们前两节介绍的Spring Security的身份认证的用户和密码在启动服务器后自动生成、代码写死或者存储到内存中,但是在实际项目中需要从动态的数据库中获取用户信息进行身份认证。Spring Security提供了一个UserDetailsService实现类JdbcUserDetailsManager来帮助我们以JDBD的方式对接数据库和Spring Security。

项目准备

添加依赖

我们使用的数据库是mysql,查询数据方式使用的是mybatis-plus因此需要引入mysql驱动和mybatis-plus依赖。

<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>

添加数据库配置

我们添加过依赖以后,需要在application.yml中添加数据库链接,实现如下:

spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver

在这里数据库的默认链接是mybatis数据库,用户名是root,密码是root,读者可以根据实际情况,自行修改

创建user和权限表:

我们这个只是实例,所以只创建一个简单的用户(sys_user)和权限(sys_authorities)两张表,sql如下:

DROPTABLEIFEXISTSsys_user;
CREATETABLEsys_user
(
`id`BIGINT(20) NOTNULLCOMMENT'主键ID',
`username`VARCHAR(30) NOTNULLCOMMENT'姓名',
`password`VARCHAR(64) NOTNULLCOMMENT'密码',
`age`INT(11) NULLDEFAULTNULLCOMMENT'年龄',
`email`VARCHAR(50) NULLDEFAULTNULLCOMMENT'邮箱',
`enabled`INT(11) notNULLDEFAULT1COMMENT'0无效用户,1是有效用户',
`phone`VARCHAR(16) NULLDEFAULTNULLCOMMENT'手机号',
`create_time`DATETIMENULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'角色的创建日期',
PRIMARYKEY (id)
)
COMMENT='用户信息表'
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB;
DROPTABLEIFEXISTSsys_authorities;
CREATETABLE`sys_authorities` (
`id`INT(11) NOTNULLAUTO_INCREMENT,
`user_id`INT(11) NOTNULLDEFAULT'0'COMMENT'角色自增id',
`authorities`VARCHAR(50) NULLDEFAULTNULLCOMMENT'权限',
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, '[email protected]',13333835911);
INSERTINTOsys_authorities (id, user_id,authorities) VALUES
(1, 1, 'admin');

实体类

创建sys_user和sys_authorities两张表对应的实体类。

sys_user实体类。

@Data
@TableName("sys_user")
publicclassUserEntity {
privateLongid;
privateStringusername;
privateStringpassword;
privateIntegerage;
privateStringemail;
privateIntegerenabled;
privateStringphone;
}

sys_authorities实体类。

@Data
@TableName("sys_authorities")
publicclassAuthoritiesEntity {
privateLongid;
privateStringUserId;
privateStringauthorities;
}

实现两个实体类的Mapper

我们使用mybatis-plus实现这两个实体类的mapper,因为这样我们(例子)可以减少代码。

publicinterfaceUserMapperextendsBaseMapper<UserEntity> {
}
publicinterfaceAuthoritiesMapperextendsBaseMapper<AuthoritiesEntity> {
}

添加@MapperScan注解

在main入口类上添加@MapperScan(“com.security.learn.mapper”)注解。

@MapperScan("com.security.learn.mapper")
@SpringBootApplication
publicclassSpringSecurityLearn3Application {
publicstaticvoidmain(String[] args) {
SpringApplication.run(SpringSecurityLearn3Application.class, args);
}
}

UserDetailsService的实现

我们需要自定义个UserDetailsService接口的实现类CustomUserDetailsService,用于实现UserDetailsService接口中的loadUserByUsername方法,通过该方法定义获取用户信息的逻辑。

UserDetailsService接口。

CustomUserDetailsService的代码实现。

@Slf4j
@Service("customUserDetailsService")
publicclassCustomUserDetailsServiceimplementsUserDetailsService {
@Autowired
privateUserMapperuserMapper;
@Autowired
privateAuthoritiesMapperauthoritiesMapper;
@Override
publicUserDetailsloadUserByUsername(Stringusername) throwsUsernameNotFoundException {
log.info("认证请求: "+username);
QueryWrapper<UserEntity>wrapper=newQueryWrapper<>();
wrapper.eq("username",username);
List<UserEntity>userEntities=userMapper.selectList(wrapper);
if (userEntities.size()>0){
QueryWrapper<AuthoritiesEntity>wrapper1=newQueryWrapper<>();
wrapper.eq("userId", userEntities.get(0).getId());
List<AuthoritiesEntity>authorities=authoritiesMapper.selectList(wrapper1);
returnnewUser(username, userEntities.get(0).getPassword(), AuthorityUtils.createAuthorityList(authorities.toString()));
}
returnnull;
}
}

重构configure(AuthenticationManagerBuilder auth)方法

重新实现configure(AuthenticationManagerBuilder auth)方法。

  • 在LearnSrpingSecurity类中注入customUserDetailsService。
  • 在configure(AuthenticationManagerBuilder auth)方法中指定认证用户方式。

代码实现如下:

@Autowired
privateUserDetailsServicecustomUserDetailsService;
/**
* 认证管理器
* 1.认证信息提供方式(用户名、密码、当前用户的资源权限)
* 2.可采用内存存储方式,也可能采用数据库方式等
* @param auth
* @throws Exception
*/
@Override
protectedvoidconfigure(AuthenticationManagerBuilderauth) throwsException {
//super.configure(auth);
// auth.inMemoryAuthentication()
// .withUser("admin")
// .password(passwordEncoder.encode("123456"))
// .roles("admin")
// .authorities("Role_admin")
// .and()
// .passwordEncoder(passwordEncoder);//配置BCrypt加密
auth.userDetailsService(customUserDetailsService);
}

测试

启动项目,访问http://localhost:8888/login/page。

使用账号密码结果为:

账号:admin。

密码:123456。

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/253603.html<

(0)
运维的头像运维
上一篇2025-04-29 23:46
下一篇 2025-04-29 23:47

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注