如何基于配置文件或特定属性禁用Spring Boot Security OAuth?
解决方案
1. 添加环境开关配置
在主配置文件application.yml中添加全局开关,默认启用OAuth2:
security: oauth2: enabled: true spring: security: oauth2: client: registration: google: client-id: 1234567890-1a2b3c4d5e6f7g8h9i0j.apps.googleusercontent.com client-secret: ABCDEF-1234-OU812_XYZZY
在需要禁用OAuth2的环境配置文件(比如application-dev.yml)中覆盖开关,并可注释掉OAuth2相关配置避免触发验证:
security: oauth2: enabled: false # spring: # security: # oauth2: # client: # registration: # google: # ...
2. 调整OAuth2认证配置类
修改GoogleOIDCSecurityConfiguration,添加条件注解控制加载时机,同时排除Spring Boot的OAuth2自动配置类,防止自动触发验证:
@Configuration @EnableWebSecurity @ConditionalOnProperty(name = "security.oauth2.enabled", havingValue = "true", matchIfMissing = true) @EnableAutoConfiguration(exclude = { OAuth2ClientAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) public class GoogleOIDCSecurityConfiguration { private static final String LOGIN_PAGE = "/login"; private static final String INVALID_SESSION_PAGE = "/invalid-session"; private static final String LOGOUT_PAGE = "/logout"; @Bean OidcUserService oidcUserService() { Set<String> scopes = Set.of( "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile" ); OidcUserService service = new OidcUserService(); service.setAccessibleScopes(scopes); return service; } @Bean SecurityFilterChain oidcFilterChain(HttpSecurity http, OidcUserService userService) throws Exception { http .authorizeHttpRequests(this::configureAuthorization) .oauth2Login(c -> configureOAuth2(c, userService)) .logout(this::configureLogout); return http.build(); } protected void configureAuthorization(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry authorize) { authorize .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR).permitAll() .requestMatchers("/*/*.js", "/*/*/*.js", "/css/**", "/lib/**", "/assets/**", "favicon.ico").permitAll() .requestMatchers("/", LOGIN_PAGE, INVALID_SESSION_PAGE, LOGOUT_PAGE).permitAll() .requestMatchers("/foo/**").hasAnyRole(Roles.FOO) .requestMatchers("/admin/**").hasRole(Roles.ADMIN) .anyRequest().authenticated(); } private void configureOAuth2(OAuth2LoginConfigurer<HttpSecurity> oauthLogin, OidcUserService userService) { oauthLogin .userInfoEndpoint(endpoint -> endpoint.oidcUserService(userService)); } private void configureLogout(LogoutConfigurer<HttpSecurity> logout) { logout.logoutSuccessUrl("/"); } }
3. 恢复原有数据库认证配置类
为原有DaoAuthenticationProvider配置类添加条件注解,仅在OAuth2开关关闭时生效:
@Configuration @EnableWebSecurity @ConditionalOnProperty(name = "security.oauth2.enabled", havingValue = "false") public class DatabaseSecurityConfiguration { private static final String LOGIN_PAGE = "/login"; private static final String INVALID_SESSION_PAGE = "/invalid-session"; private static final String LOGOUT_PAGE = "/logout"; @Autowired private DataSource dataSource; @Bean DaoAuthenticationProvider daoAuthenticationProvider() { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(userDetailsService()); provider.setPasswordEncoder(passwordEncoder()); return provider; } @Bean UserDetailsService userDetailsService() { return new JdbcUserDetailsManager(dataSource); } @Bean PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean SecurityFilterChain databaseFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(this::configureAuthorization) .formLogin(form -> form.loginPage(LOGIN_PAGE).permitAll()) .logout(this::configureLogout) .authenticationProvider(daoAuthenticationProvider()); return http.build(); } protected void configureAuthorization(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry authorize) { // 保持和OAuth2配置一致的权限规则 authorize .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR).permitAll() .requestMatchers("/*/*.js", "/*/*/*.js", "/css/**", "/lib/**", "/assets/**", "favicon.ico").permitAll() .requestMatchers("/", LOGIN_PAGE, INVALID_SESSION_PAGE, LOGOUT_PAGE).permitAll() .requestMatchers("/foo/**").hasAnyRole(Roles.FOO) .requestMatchers("/admin/**").hasRole(Roles.ADMIN) .anyRequest().authenticated(); } private void configureLogout(LogoutConfigurer<HttpSecurity> logout) { logout.logoutSuccessUrl("/"); } }
关键说明
- 借助
@ConditionalOnProperty实现两个配置类的互斥加载:开关开启时加载OAuth2配置,否则加载数据库认证配置。 - 在OAuth2配置类中排除自动配置类,避免Spring Boot自动触发OAuth2相关验证,解决client-id不能为空的异常。
- 两个配置类保持相同的权限规则,确保不同认证方式下的访问控制逻辑统一。
内容的提问来源于stack exchange,提问作者E-Riz
相关产品推荐
相关产品推荐

