Spring OAuth redirect_uri不使用https

Zac*_*ann 19 oauth spring-boot

我有一个Spring Boot 1.3.0应用程序,其中包含Spring Security OAuth作为一种SSO集成.

问题是应用程序在非SSL环境中运行,负载均衡器(F5)后面有非标准端口强制SSL,OAuth提供商要求所有重定向URL都注册为https,但Spring OAuth客户端(自动) - 使用@EnableOAuthSso配置)只会使用以下URL重定向到OAuth提供程序...

https:// [provider_host]/oauth/authorize?client_id = [redact] &redirect_uri = http:// [application_host]/login&response_type = code&scope = [redact]&state = IpMYTe

请注意,返回redirect_uri生成为http.即使F5会在返回途中强制它进行https,我们的OAuth提供程序也不允许使用非SSL重定向URI.我该如何配置?

除了我的Spring Data JPA控制器,这是整个应用程序......

AppConfig.java

@SpringBootApplication(exclude = { HibernateJpaAutoConfiguration.class })
@EnableJpaRepositories
public class AppConfig extends SpringBootServletInitializer {

    public static void main(final String... args) {
        SpringApplication.run(AppConfig.class, args);
    }

    @Autowired
    public DataSource dataSource;

    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryInfo() {
        final LocalContainerEntityManagerFactoryBean fac = new LocalContainerEntityManagerFactoryBean();
        fac.setDataSource(dataSource);
        fac.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        fac.setPackagesToScan("[redact]");

        final Properties props = new Properties();
        props.put("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
        props.put("hibernate.show_sql", "true");
        props.put("hibernate.format_sql", "true");
        fac.setJpaProperties(props);

        return fac;
    }

    @Bean(name = "transactionManager")
    public PlatformTransactionManager getTransactionManager() {
        final JpaTransactionManager transactMngr = new JpaTransactionManager();
        transactMngr.setEntityManagerFactory(getEntityManagerFactoryInfo().getObject());
        return transactMngr;
    }

}
Run Code Online (Sandbox Code Playgroud)

SecurityConfig.java

@Configuration
@EnableOAuth2Sso
public class SecurityConfig {

}
Run Code Online (Sandbox Code Playgroud)

application.properties

server.port=9916
server.contextPath=

server.use-forward-headers=true

security.oauth2.client.clientId=[redact]
security.oauth2.client.clientSecret=[redact]
security.oauth2.client.scope=[redact]
security.oauth2.client.accessTokenUri=https://[provider_host]/oauth/token
security.oauth2.client.userAuthorizationUri=https://[provider_host]/oauth/authorize
security.oauth2.resource.userInfoUri=https://[provider_host]/oauth/me
security.oauth2.resource.preferTokenInfo=false

logging.level.org.springframework=TRACE
Run Code Online (Sandbox Code Playgroud)

Zac*_*ann 22

在手动挖掘配置类之后,我能够找到并添加以下内容,这就是诀窍......

security.oauth2.client.pre-established-redirect-uri=https://[application_host]/login
security.oauth2.client.registered-redirect-uri=https://[application_host]/login
security.oauth2.client.use-current-uri=false
Run Code Online (Sandbox Code Playgroud)

我不相信没有更好的方法来解决强制HTTPS重定向URL的问题,但是此修复程序对我有用.


Mik*_*ike 14

您可能需要确保您的应用程序了解x-forwarded负载均衡器中的标头.

把它放在我的application.yml中修复了我与AWS ELB背后的应用程序非常相似的问题:

server:
  tomcat:
    remote-ip-header: x-forwarded-for
    protocol-header: x-forwarded-proto
Run Code Online (Sandbox Code Playgroud)

编辑:使用更通用的配置可以简化:

server:
  use-forward-headers: true
Run Code Online (Sandbox Code Playgroud)

  • 请注意,从 Spring Boot 2.2 开始。您应该使用 `server.forward-headers-strategy=native` 而不是 `server.use-forward-headers`,请参阅 /sf/ask/4138856291/ -headers-in-spring-boot-2-2-0-spring-web-mvc-behin (2认同)

小智 12

我的答案是针对使用最新春季版本的人,因为上面建议的答案对我不起作用。我正在使用 Spring Boot 2.3.5.RELEASE。

我遇到了同样的问题,我使用 Azure AD 进行 oauth2 身份验证。我的应用程序在反向代理后面运行,并且形成的重定向 uri 采用 http 而不是 https。

阅读文档https://docs.spring.io/spring-security/site/docs/5.2.x/reference/html/oauth2.html#oauth2Client-auth-code-redirect-uri后 ,我在application.properties 文件,它对我有用

spring.security.oauth2.client.registration.azure.redirect-uri=https://{baseHost}{basePort}{basePath}/login/oauth2/code/azure
Run Code Online (Sandbox Code Playgroud)


Gay*_*hne 5

既然您提到了 oauth 的使用,我认为这将有助于某人理解操作流程。此答案仅适用于您使用反向代理(例如 NGINX)的情况。

问题的原因,  

您的 Spring Boot 应用程序正在服务器上运行,地址类似于http://localhost:8080。这就是所有 Spring Boot 应用程序对其主机的了解。如果您检查 facebook(或其他 oauth 客户端)错误页面中的重定向 url,则可以检查此行为。它看起来像https://graph.facebook.com/v3.0/me?fields=id,first_name,middle_name,last_name,name,email,verified,is_verified,picture.width(250).height(250) ,link&redirect_url=http%3A%2F%2Flocalhost%2Flogin%2Ffacebook

看看redirect_url是错误的。

因此,我们需要以某种方式告诉应用程序它托管在该地址下。

快速解决

如果您只想修复 Facebook OAuth(或其他 oAuth 提供商),则向客户端添加以下行即可修复。

facebook:
  client:
     preEstablishedRedirectUri: https://yourdomain.com/
     useCurrentUri: false
Run Code Online (Sandbox Code Playgroud)

但是,这只能解决当前的问题(也不灵活)。但如果您需要更具体的可移植解决方案,则需要在反向代理处解决此问题。

打开应用程序的 nginx 配置并更改它,如下所示。

location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Will add the user's ip to the request, some apps need this
        proxy_set_header X-Forwarded-Proto $scheme; # will forward the protocole i.e. http, https
        proxy_set_header X-Forwarded-Port $server_port; # Will forward the port 
        proxy_set_header Host $host;                    # !Important will forward the host address
        proxy_pass http://localhost:8080/;
}
Run Code Online (Sandbox Code Playgroud)

好的,现在,nginx 正在将之前隐藏的信息发送到 spring boot 应用程序。但是,Spring 应用程序尚未使用此信息。要告诉它使用这些信息,请将以下行添加到 application.yml 中。

server.use-forward-headers = true
Run Code Online (Sandbox Code Playgroud)

如果您的反向代理位于同一网络的不同节点,您可能需要使用以下内容配置反向代理服务器的 IP。(替换为您的IP)

server.tomcat.internal-proxies=192\.65\.210\.55
Run Code Online (Sandbox Code Playgroud)