Java框架快速入门: Spring Security+OAuth2之自定义数据库表结构实现认证

发布时间:2026/9/11 16:27:51
Java框架快速入门: Spring Security+OAuth2之自定义数据库表结构实现认证 纲要Spring Security 内建 JDBC 认证的局限自定义数据库认证的整体思路项目依赖与工程结构编写初始化 SQL 脚本schema.sql与data.sql控制脚本加载策略spring.sql.init.modeembedded安全配置基于AuthenticationManagerBuilder自定义查询启动验证与数据库检查深入定制修改表名与字段名总结Spring Security 提供了内建的 JDBC 用户存储支持通过withDefaultSchema()可以自动创建默认的表结构users和authorities。但真实项目中表结构往往更复杂表名、字段名可能都有定制需求直接使用默认结构并不现实。Spring Security 为此提供了非常灵活的扩展点我们只需提供两条 SQL 查询框架就能完全适配任何自定义的用户‑权限表。本文将通过一个完整可运行的 Spring Boot 示例展示如何从零开始实现数据库认证的定制化。项目依赖与工程结构首先创建一个标准的 Spring Boot 项目引入spring-boot-starter-security、spring-boot-starter-web、spring-boot-starter-jdbc以及嵌入式数据库 H2。!-- pom.xml --projectxmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.0/version/parentgroupIdcom.example/groupIdartifactIdcustom-jdbc-auth/artifactIdversion1.0.0/versionpropertiesjava.version17/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependencydependencygroupIdcom.h2database/groupIdartifactIdh2/artifactIdscoperuntime/scope/dependency/dependencies/project项目结构如下src └── main ├── java │ └── com │ └── example │ ├── CustomJdbcAuthApplication.java │ └── config │ └── SecurityConfig.java └── resources ├── application.properties ├── schema.sql └── data.sql编写数据库初始化脚本我们需要自定义两张表mock_users存储用户信息mock_authorities存储权限。在resources目录下放置schema.sql和data.sqlSpring Boot 会自动识别并在启动时执行需结合初始化模式配置。-- schema.sqlCREATETABLEIFNOTEXISTSmock_users(usernameVARCHAR(50)NOTNULLPRIMARYKEY,passwordVARCHAR(500)NOTNULL,enabledBOOLEANNOTNULL,nameVARCHAR(100)-- 额外扩展字段允许为空);CREATETABLEIFNOTEXISTSmock_authorities(idBIGINTAUTO_INCREMENTPRIMARYKEY,usernameVARCHAR(50)NOTNULL,authorityVARCHAR(50)NOTNULL,CONSTRAINTfk_authorities_usersFOREIGNKEY(username)REFERENCESmock_users(username));-- data.sqlINSERTINTOmock_users(username,password,enabled,name)VALUES(user,{noop}123456,true,Normal User),(admin,{noop}admin,true,Administrator);INSERTINTOmock_authorities(username,authority)VALUES(user,ROLE_USER),(admin,ROLE_ADMIN);密码前缀{noop}表示使用明文密码编码器仅用于演示生产环境务必使用BCrypt等加密方式。控制初始化脚本的加载策略在生产环境我们通常不希望每次启动都执行初始化脚本以免清空已有数据。Spring Boot 提供了spring.sql.init.mode属性来控制脚本执行时机使用embedded表示只在嵌入式数据库如 H2、Derby时执行连接外部数据库时则跳过。# application.properties spring.sql.init.modeembedded spring.datasource.urljdbc:h2:mem:testdb spring.datasource.driverClassNameorg.h2.Driver spring.datasource.usernamesa spring.datasource.password spring.h2.console.enabledtrue这样一来开发阶段使用内嵌 H2 可自动建表并插入测试数据切换到 MySQL 等外部数据库时脚本不会执行保证数据安全。安全配置基于自定义查询的 JDBC 认证核心配置类SecurityConfig中我们通过AuthenticationManagerBuilder的jdbcAuthentication()方法设置数据源及两条关键查询usersByUsernameQuery根据用户名查询用户信息必须返回username、password、enabled三列顺序及别名必须匹配。authoritiesByUsernameQuery根据用户名查询权限列表必须返回username和authority两列。即使我们使用了与默认不同的表名和字段名只要 SQL 查询的返回列别名正确框架就能完全适配。packagecom.example.config;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.crypto.factory.PasswordEncoderFactories;importorg.springframework.security.crypto.password.PasswordEncoder;importorg.springframework.security.web.SecurityFilterChain;importjavax.sql.DataSource;importstaticorg.springframework.security.config.Customizer.withDefaults;ConfigurationEnableWebSecuritypublicclassSecurityConfig{BeanpublicSecurityFilterChainfilterChain(HttpSecurityhttp)throwsException{http.authorizeHttpRequests(authz-authz.requestMatchers(/admin/**).hasRole(ADMIN).anyRequest().authenticated()).httpBasic(withDefaults());returnhttp.build();}BeanpublicPasswordEncoderpasswordEncoder(){// 使用委托密码编码器支持 {noop}、{bcrypt} 等前缀returnPasswordEncoderFactories.createDelegatingPasswordEncoder();}// 通过注入 AuthenticationManagerBuilder 并调用 jdbcAuthentication 进行自定义// 更推荐的方式直接在 configure(AuthenticationManagerBuilder) 中配置// 此处采用新的风格通过注入 DataSource 并以 Bean 方式配置// 实际可根据习惯选用BeanpublicvoidconfigureGlobal(AuthenticationManagerBuilderauth,DataSourcedataSource)throwsException{auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery(SELECT username, password, enabled FROM mock_users WHERE username ?).authoritiesByUsernameQuery(SELECT username, authority FROM mock_authorities WHERE username ?).passwordEncoder(passwordEncoder());}}启动类CustomJdbcAuthApplication.java非常简单packagecom.example;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplicationpublicclassCustomJdbcAuthApplication{publicstaticvoidmain(String[]args){SpringApplication.run(CustomJdbcAuthApplication.class,args);}}启动验证启动应用后Spring Boot 会自动执行schema.sql和data.sql在 H2 内存库中创建MOCK_USERS和MOCK_AUTHORITIES表并插入数据。通过浏览器访问http://localhost:8080/h2-console使用 JDBC URLjdbc:h2:mem:testdb连接可以查看到两张表的内容。使用 curl 测试认证# 访问受保护资源使用 user/123456 认证curl-uuser:123456 http://localhost:8080/any-path若配置了/admin路径需要 ADMIN 角色使用admin:admin即可访问。深入定制修改表名与字段名上述配置中SQL 返回列已经使用了别名来匹配框架的预期名称。如果实际业务表中用户名字段为login_name密码字段为pwd状态字段为active只需调整usersByUsernameQuerySELECTlogin_nameASusername,pwdASpassword,activeASenabledFROMmy_usersWHERElogin_name?同理权限表若字段不同也可以通过别名映射。这便是 Spring Security JDBC 认证最灵活的定制方式无需重写UserDetailsService仅靠两条 SQL 即可接入任何遗留系统的用户数据。总结本文从 Spring Security 默认 JDBC 存储的局限出发完整演示了如何通过自定义schema.sql和data.sql初始化表结构结合spring.sql.init.modeembedded控制脚本执行并在安全配置中使用两条查询语句适配任意用户‑权限表。这种方式不仅适用于纯 JDBC 环境当与 MyBatis 等框架配合时也同样简便为后续深度定制如整合 JPA 实现统一风格打下了良好基础。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询