如何让OAuth2服务器从数据库读取客户端而非内存存储?
SpringBoot 2.7.3 从数据库读取OAuth2客户端凭证方案
1. 引入适配依赖
SpringBoot 2.7.3 需搭配 Spring Security OAuth2 Authorization Server 0.3.1(版本严格对应,避免依赖冲突),Maven 依赖配置如下:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-authorization-server</artifactId> <version>0.3.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- MySQL驱动,按需替换为其他数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
2. 初始化数据库表
执行官方提供的MySQL适配SQL,创建存储客户端凭证的表:
CREATE TABLE oauth2_registered_client ( id VARCHAR(100) NOT NULL, client_id VARCHAR(100) NOT NULL, client_id_issued_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, client_secret VARCHAR(200) DEFAULT NULL, client_secret_expires_at TIMESTAMP NULL, client_name VARCHAR(200) NOT NULL, client_authentication_methods VARCHAR(1000) NOT NULL, authorization_grant_types VARCHAR(1000) NOT NULL, redirect_uris VARCHAR(1000) DEFAULT NULL, post_logout_redirect_uris VARCHAR(1000) DEFAULT NULL, scopes VARCHAR(1000) NOT NULL, client_settings VARCHAR(2000) NOT NULL, token_settings VARCHAR(2000) NOT NULL, PRIMARY KEY (id) );
手动插入测试数据时,client_secret需用BCrypt加密,示例:
INSERT INTO oauth2_registered_client (id, client_id, client_secret, client_name, client_authentication_methods, authorization_grant_types, redirect_uris, scopes, client_settings, token_settings) VALUES ('1', 'test-client', '{bcrypt}$2a$10$Z8HxQx9eU7G8kL5y6M4N3O2P1Q0R9S8T7U6V5W4X3Y2Z1A0B9C8D7E6F5G4', 'Test Client', 'client_secret_basic', 'authorization_code,refresh_token', 'http://localhost:8080/login/oauth2/code/test-client', 'read,write', '{"@class":"org.springframework.security.oauth2.server.authorization.settings.ClientSettings","requireAuthorizationConsent":false}', '{"@class":"org.springframework.security.oauth2.server.authorization.settings.TokenSettings","accessTokenTimeToLive":"PT1H","refreshTokenTimeToLive":"PT7D"}');
3. 配置数据库版客户端存储
使用官方提供的JdbcRegisteredClientRepository,直接注入数据源即可实现从数据库读取客户端凭证,无需自定义实现:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import javax.sql.DataSource; @Configuration public class OAuth2ClientConfig { @Bean public RegisteredClientRepository registeredClientRepository(DataSource dataSource) { return new JdbcRegisteredClientRepository(dataSource); } }
4. 配置授权服务器安全链
配置Spring Security授权服务器的基础过滤规则,确保客户端凭证校验逻辑生效:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; @EnableWebSecurity @Configuration public class SecurityConfig { @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); // 可选:启用OIDC功能 http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(oidc -> oidc.enabled(true)); // 未认证时跳转登录页 http.exceptionHandling(exceptions -> exceptions .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))); return http.build(); } }
5. 配置数据库连接
在application.yml中添加数据库连接信息:
spring: datasource: url: jdbc:mysql://localhost:3306/oauth2_db?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC username: root password: your-db-password driver-class-name: com.mysql.cj.jdbc.Driver
该方案完全替代了旧版已弃用的ClientDetailsService相关实现,适配SpringBoot 2.7.3的版本要求,使用官方推荐的OAuth2授权服务器组件完成客户端凭证的数据库读取。
内容的提问来源于stack exchange,提问作者vunhatchuong
相关产品推荐
相关产品推荐

