我有一个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 =代码&安培;范围= [纂]&安培;状态= IpMYTe
请注意,返回redirect_uri将生成为http。即使F5会在返回途中强制它进行https,我们的OAuth提供程序也不允许使用非SSL重定向URI。我该如何配置?
除了我的Spring Data JPA控制器,这是整个应用程序...
@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;
}
}
@Configuration
@EnableOAuth2Sso
public class SecurityConfig {
}
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
答案 0 :(得分:18)
在手动挖掘配置类之后,我能够找到并添加以下内容,这就是诀窍......
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重定向网址的问题,但此修复程序对我有用。
答案 1 :(得分:8)
您可能需要确保您的应用程序了解负载均衡器中的x-forwarded
标头。
将它放在我的application.yml中修复了我在AWS ELB背后的应用程序非常类似的问题:
server:
tomcat:
remote-ip-header: x-forwarded-for
protocol-header: x-forwarded-proto
编辑:这可以通过更通用的配置进行简化:
server:
use-forward-headers: true
答案 2 :(得分:1)
我遇到了同样的问题。 我在redirect_uri中添加了这两个参数来强制HTTPS:
preEstablishedRedirectUri: https://...
useCurrentUri: false
它有效:" redirect_uri"现在正在使用HTTPS
答案 3 :(得分:0)
您可能需要使用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
答案 4 :(得分:0)
自从您提到使用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应用程序未使用此信息。要告诉它使用这些信息,请将以下行添加到application.yml。
server.use-forward-headers = true
如果您的反向代理位于同一网络的不同节点中,则可能需要使用以下配置反向代理服务器的IP。 (替换为您的IP)
server.tomcat.internal-proxies=192\.65\.210\.55
答案 5 :(得分:0)
我的答案是给使用最新春季版本的人的,因为上面建议的答案对我不起作用。我正在使用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