You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring 5 Google OAuth2需配置HTTPS回调URL而非HTTP的解决方案

问题描述

我的站点部署在Apache httpd(端口80、443)和Wildfly 15(端口8080)上,Apache通过以下反向代理配置与Wildfly通信:

ProxyPass        / http://myhost.com:8080/
ProxyPassReverse / http://myhost.com:8080/

我把基于Java 11的Spring 5应用打成WAR包部署在Wildfly上,应用用Google OAuth2实现用户认证。现在要调用YouTube API,但这类API要求授权回调URI必须是HTTPS。目前只有配置http://myhost.com:8080/login/oauth2/code/google才能正常登录,这和YouTube API的要求冲突。

我明白回调用HTTP+8080是因为请求来自Wildfly上的应用,但我需要把回调URI改成https://myhost.com/login/oauth2/code/google,该怎么配置?

以下是我已有的配置,但没生效:

现有Spring Security配置

@PropertySource("classpath:application.properties")
@Configuration
@EnableWebSecurity
public class SecurityConfiguration
{
  @Value("${spring.security.oauth2.client.registration.google.redirect-uri}")
  private String             redirectUri;

  @Bean
  public SecurityFilterChain filterChain(
    HttpSecurity http) throws Exception
  {
    http.cors().and().csrf().disable()//

    .authorizeRequests()//
    .antMatchers("/secure/**").authenticated()//
    .antMatchers("/api/**", "/login/**").permitAll()// for redirectUri
    .antMatchers("/**").permitAll()//
    .antMatchers("/logout").permitAll()//

    .and()//
    .sessionManagement()//
    .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)

    .and()//
    .userDetailsService(userDetailsManager())//
    .oauth2Login()// because we need to authorize our users, not just be a web client
    //.oauth2Client()// not this
    .redirectionEndpoint().baseUri(this.redirectUri)//
    .and()//
     .clientRegistrationRepository(this.securityService.getClientRegistrationRepository())//
    .authorizedClientService(this.securityService.getAuthorizedClientService())//
    .loginPage(SecurityController.LOGIN_PAGE_MAPPING)//
    .defaultSuccessUrl(loginSuccessUrl)//
    //.successHandler(this.loginSuccessHandler)//
    .failureUrl("/login-failure-page")//

    .and()//
    .logout()//
    .clearAuthentication(true)//
    .invalidateHttpSession(true)//
    .deleteCookies("JSESSIONID")//
    .logoutSuccessUrl(SecurityController.LOGOUT_PAGE_MAPPING).permitAll()

    // Gotta get back to the correct port after login.
    .and()//
    .requestCache().requestCache(requestCache()); // port mapper here

    // For Firefox and h2-console
    http.headers().frameOptions().disable();

    return http.build();
  }
}

application.properties配置

spring.security.oauth2.client.registration.google.redirect-uri=https://myhost.com/login/oauth2/code/google
spring.security.oauth2.client.registration.google.redirectUri=https://myhost.com/login/oauth2/code/google
spring.security.oauth2.client.registration.google.preEstablishedRedirectUri=https://myhost.com/login/oauth2/code/google
spring.security.oauth2.client.use-current-uri=false

CORS配置

@Bean
public WebMvcConfigurer corsConfigurer()
{
  return new WebMvcConfigurer()
  {
    @Override
    public void addCorsMappings(
      CorsRegistry registry)
    {
      registry.addMapping("/**")//
        .allowedOrigins(/*"http://myhost.com:8080",*/ "https://myhost.com",
            "https://myhost.com:8080")//
        .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
    }
  };
}

解决方案

要解决这个问题,得从Apache反向代理和Spring应用内部两个层面调整,确保Spring能识别外部的HTTPS请求,同时正确生成符合要求的回调URI。

1. 完善Apache反向代理配置

当前的代理配置没传递HTTPS相关头信息,导致Wildfly/Spring误以为请求是HTTP的。需要添加头信息让Spring知道外部是HTTPS协议:

ProxyPass        / http://myhost.com:8080/
ProxyPassReverse / http://myhost.com:8080/
# 传递HTTPS协议和端口信息
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
# 传递正确的Host头,避免Spring生成错误的URI
RequestHeader set Host "myhost.com"

注意要确保Apache的mod_headers模块已经启用(可以用a2enmod headers命令启用)。

2. 让Spring识别反向代理的HTTPS请求

Spring需要知道自己运行在反向代理之后,要启用ForwardedHeaderFilter来处理上面添加的X-Forwarded-*头:

@Bean
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
    FilterRegistrationBean<ForwardedHeaderFilter> filterRegistrationBean = new FilterRegistrationBean<>();
    filterRegistrationBean.setFilter(new ForwardedHeaderFilter());
    // 设置最高优先级,确保先处理头信息
    filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return filterRegistrationBean;
}

如果是Spring Boot环境,也可以直接在application.properties里加配置:

server.forward-headers-strategy=NATIVE

3. 简化OAuth2回调URI配置

你当前的application.properties里有重复配置,只保留必要的即可,同时确保和Google控制台的配置一致:

# 只保留这一行,和Google控制台里的回调URI完全匹配
spring.security.oauth2.client.registration.google.redirect-uri=https://myhost.com/login/oauth2/code/google
# 禁用自动使用当前请求URI,强制用配置的固定值
spring.security.oauth2.client.use-current-uri=false

同时,去Google Cloud控制台的OAuth2客户端配置页面,把回调URI更新为https://myhost.com/login/oauth2/code/google,删掉旧的HTTP+8080的条目。

4. 调整SecurityFilterChain配置

不需要手动给redirectionEndpoint指定完整的URL,Spring会根据识别到的外部协议自动生成正确的回调URI,把这部分代码修改为:

.oauth2Login()
// 移除手动设置的baseUri,让Spring自动处理
// .redirectionEndpoint().baseUri(this.redirectUri).and()
.clientRegistrationRepository(this.securityService.getClientRegistrationRepository())
.authorizedClientService(this.securityService.getAuthorizedClientService())
// 其余配置保持不变

5. 优化CORS配置(可选)

当前CORS配置里的https://myhost.com:8080可以移除,因为外部用户只会通过443端口访问:

@Bean
public WebMvcConfigurer corsConfigurer() {
  return new WebMvcConfigurer() {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
      registry.addMapping("/**")
        .allowedOrigins("https://myhost.com")
        .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
    }
  };
}

验证步骤

  1. 重启Apache和Wildfly服务
  2. 访问https://myhost.com尝试登录,检查Google授权页面显示的回调URI是否为HTTPS格式
  3. 登录成功后,测试YouTube API的调用是否正常

内容的提问来源于stack exchange,提问作者Gary Kephart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:18:14