在单个Spring Boot应用中实现Spring OAuth2.0授权与资源服务
Spring Security 5.7.x 替代旧版OAuth自动配置方案
核心背景
Spring Security 5.x之后,官方废弃了原有的spring-security-oauth2-autoconfigure模块,将OAuth2相关功能拆分为授权服务器、资源服务器、客户端三个独立组件,不再提供一键式自动配置,但仍有轻量化方案可接近旧版开发体验。
1. 复用旧版风格的简化实现(依赖第三方兼容starter)
官方虽不再维护原自动配置,但社区提供了实验性兼容starter,可快速恢复类似旧版的自动配置能力:
- 添加依赖:在
pom.xml中引入org.springframework.security.experimental:spring-security-oauth2-authorization-server-autoconfigure - 配置文件沿用旧版OAuth2参数示例:
spring.security.oauth2.authorization-server.client.my-client.client-id=client1 spring.security.oauth2.authorization-server.client.my-client.client-secret=secret1 spring.security.oauth2.authorization-server.client.my-client.scopes=read,write spring.security.oauth2.authorization-server.client.my-client.authorized-grant-types=authorization_code,refresh_token - 启动类无需额外注解,依赖会自动配置授权服务、资源服务的核心逻辑。
2. 官方原生轻量化配置(单应用内集成,无需拆分服务)
若不想依赖第三方组件,可通过Spring Security 5.7.x原生配置类,在单体应用内快速搭建OAuth2服务,接近旧版简洁性:
授权服务+资源服务合一配置
创建配置类,同时完成授权服务器与资源服务器的配置:
@Configuration public class OAuth2Config { // 配置客户端信息(内存存储,生产环境可替换为数据库实现) @Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient client = RegisteredClient.withId(UUID.randomUUID().toString()) .clientId("my-client") .clientSecret("{noop}my-secret") // 生产环境请用BCrypt等加密方式 .scope("read") .scope("write") .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) .redirectUri("http://localhost:8080/login/oauth2/code/my-client") .build(); return new InMemoryRegisteredClientRepository(client); } // 配置授权服务器核心端点 @Bean public OAuth2AuthorizationServerConfiguration authorizationServerConfiguration() { return OAuth2AuthorizationServerConfiguration.builder() .registeredClientRepository(registeredClientRepository()) .build(); } // 配置资源服务器规则 @Bean public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt.jwtAuthenticationConverter(new JwtAuthenticationConverter())) ); return http.build(); } // 配置身份验证管理器 @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return config.getAuthenticationManager(); } }
同应用内客户端配置
如果是单体应用内的客户端调用,配置OAuth2AuthorizedClientManager即可实现令牌管理:
@Bean public OAuth2AuthorizedClientManager authorizedClientManager( ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientService authorizedClientService) { OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder() .authorizationCode() .refreshToken() .build(); DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager( clientRegistrationRepository, authorizedClientService); authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); return authorizedClientManager; }
3. 关于服务拆分的说明
官方推荐拆分服务是为了适配微服务架构的扩展性,但如果是单体应用,完全可以在一个应用内同时配置授权、资源、客户端,无需拆分,这种方式和旧版单应用集成的体验基本一致。
内容的提问来源于stack exchange,提问作者francissoria
相关产品推荐
相关产品推荐

