【问题标题】:Spring OAuth redirect_uri not using httpsSpring OAuth redirect_uri 不使用 https
【发布时间】:2016-02-22 02:26:50
【问题描述】:

我有一个 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;
    }

}

SecurityConfig.java

@Configuration
@EnableOAuth2Sso
public class SecurityConfig {

}

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

【问题讨论】:

  • 我遇到了类似的问题,但不是想成为 HTTPS,而是当我想要 HTTP 时,URI 总是以 HTTPS 的形式返回给我。你知道如何做同样的事情,但方向相反吗?我已经将您的答案应用于 application.properties 文件,但没有成功。

标签: oauth spring-boot


【解决方案1】:

您可能需要使用spring.oauth2.client.access-token-uri

配置参数在 1.3.0.M1 之后改变

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.3.0-M1-Configuration-Changelog

【讨论】:

  • "security.oauth2.client.accessTokenUri" 我相信仍然以这种方式运行。
  • 0 否决票 它如何在验证后处理重定向。 OAuth2ClientAuthenticationProcessingFilter 是由 @@EnableOAuth2Sso 添加的,所以我没有办法重定向。默认重定向是“/”(上下文),它再次使用 http。有人成功完成这项工作吗?
【解决方案2】:

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

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

我不相信没有更好的方法来解决强制 HTTPS 重定向 URL 的问题,但这个修复对我有用。

【讨论】:

  • 您知道是否有任何已发布的文档说明这四个属性的作用吗?
  • @Mark 不,我通过挖掘 Spring 属性元数据以查看它们映射到哪些 bean 找到了有关这些的信息。不幸的是,我没有在某处追踪它。
  • 这个设置救了我的命……感谢 Zack。它们在 org.springframework.security.oauth2.client.token.grant.redirect.AbstractRedirectResourceDetails 中定义。
  • 你能提供这个 github repo 的完整例子吗?花了这么多小时,但仍然坚持使用 redirect_uri。
  • 重定向 uri 可以使用外部 URL 吗?
【解决方案3】:

您可能需要确保您的应用程序能够理解来自负载均衡器的 x-forwarded 标头。

将它放在我的application.yml 中解决了我与 AWS ELB 后面的应用程序非常相似的问题:

server:
  tomcat:
    remote-ip-header: x-forwarded-for
    protocol-header: x-forwarded-proto

编辑:这可以通过更通用的配置来简化:

server:
  use-forward-headers: true

对于 Apache Tomcatserver.xml 中使用 RemoteIpValve(在 AccessLogValve 上方):

    <Valve className="org.apache.catalina.valves.RemoteIpValve" 
        protocolHeader="X-Forwarded-Proto" />

另请参阅:https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html

【讨论】:

  • 我同意 Carlos,OP,这是我为最新版本的 Spring Security 找到的最佳答案。我正在使用 Spring 5.1.9.RELEASE、Spring Security 5.1.6.Release 和 Spring Boot 2.1.8.RELEASE。
  • 我在 ALB 后面的 AWS 中。接受的答案没有影响。这个答案做到了。
  • @ImtiazShakilSiddique 添加了有关 RemoteIpValve 的信息。您应该可以在 Tomcat 6 及更高版本中使用它。
  • 感谢更新答案@Nux,我也解决了RemoteIpValve的问题
  • 请注意,从 Spring Boot 2.2 开始。你应该使用server.forward-headers-strategy=native 而不是server.use-forward-headers,见stackoverflow.com/questions/59126518/…
【解决方案4】:

我遇到了同样的问题。 我添加了这两个参数以在 redirect_uri 中强制使用 HTTPS:

preEstablishedRedirectUri: https://...
useCurrentUri: false

有效:“redirect_uri”现在使用 HTTPS

【讨论】:

  • 您在哪里进行了这些更改?你能提供更多细节吗?
  • 您必须在 Spring oauth 属性中进行此更改。如果您使用单独的配置,则可以使用 OAuth2RestTemplate 并使用 OAuth2ProtectedResourceDetails 设置这些属性。我这样做了,它有效。
【解决方案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

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

打开应用程序的 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/;
}

好的,现在,nginx 正在将之前隐藏的信息发送到 spring boot 应用程序。但是,spring app 并没有使用这些信息。为了告诉它使用这些信息,将以下行添加到 application.yml。

server.use-forward-headers = true

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

server.tomcat.internal-proxies=192\.65\.210\.55

【讨论】:

    【解决方案6】:

    我的答案适用于使用最新春季版本的人,因为上面建议的答案对我不起作用。我正在使用 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
    

    【讨论】:

    • 谢谢,这就像做梦一样。我对每个提供者的路径进行了硬编码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 2015-06-20
    • 2019-11-09
    • 2018-04-09
    • 2016-09-19
    • 1970-01-01
    相关资源
    最近更新 更多