使用Spring Cloud OAuth2的SSL /代理问题

我改编了以下的OAuth2 Spring Cloud示例:

Authserver / SSO

我所做的唯一更改是在Authserver端使用JPA来检查数据库中的凭据。 一切运作良好,除了在nginx代理之后部署。 正如上面的示例应用程序中所使用的,使用Spring Boot和embedded式Tomcat。 我也正确configuration了代理标题:

server.tomcat.protocol-header=X-Forwarded-Proto server.tomcat.remote-ip-header=X-Real-IP 

代理HTTP正在工作:

 accessTokenUri: http://uaa.sample.com/oauth/token userAuthorizationUri: http://uaa.sample.com/oauth/authorize 

到目前为止这么好,但我需要使用SSL(显然):

 accessTokenUri: https://uaa.sample.com/oauth/token userAuthorizationUri: https://uaa.sample.com/oauth/authorize 

如果我切换到SSL,auth服务器从授权redirect后,我从我的客户端应用程序得到一个401。 我捕获的HTTPstream量,似乎一切工作:

  • GET请求到客户端应用程序
  • 客户端应用程序redirect到/login
  • / loginredirect到https://uaa.sample.com/oauth/authorize?client_id=reprisk&redirect_uri=http://test.sample.com/login&response_type=code&state=9prwi2
  • Auth服务器redirect到https://uaa.sample.com/login
  • login后,再次调用授权,服务器最终redirect到http://test.sample.com/login?code=212eRK&state=9prwi2

HTTP和HTTPS的HTTPstream量是完全一样的,除了HTTP为最后一个请求设置了正确的引用者(AFAIK,在OAuth身份validation期间没有检查到引用者,对吧?):

HTTP:

 GET /login?code=212eRK&state=9prwi2 HTTP/1.1 Host: test.sample.com ... Referer: http://uaa.sample.com/login Cookie: JSESSIONID=401EB8D1D1F4297160D518EC253A0CB5; XSRF-TOKEN=95a00a0d-3362-4e9b-b7eb-45addf2d10b4 ... --- HTTP/1.1 302 Found 

HTTPS:

 GET /login?code=212eRK&state=9prwi2 HTTP/1.1 Host: test.sample.com ... Cookie: JSESSIONID=401EB8D1D1F4297160D518EC253A0CB5; XSRF-TOKEN=95a00a0d-3362-4e9b-b7eb-45addf2d10b4 ... --- HTTP/1.1 401 Unauthorized 

客户端应用程序的相应日志消息

 Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Could not obtain access token. 

任何想法为什么使用代理和SSL不起作用? 我很高兴分享更多的代码和/或日志输出!

谢谢!!!

它似乎失败了SSO应用程序尝试交换令牌的身份验证代码的位置。 之前的所有步骤都是浏览器重定向,这是SSO服务器上的代码,用于调用auth服务器。 您在auth服务器上使用什么SSL证书? 他们是否在Java信任存储中由具有CA的可信方签名? 如果没有,那么这可能是因为BadCredentialsException是底层HTTP请求失败的最终结果而失败的原因。

另一种选择是没有直接从SSO服务器到Auth服务器地址的路由。

我相信最终是Apache Commons HttpClient代码将会处理这个请求,所以你应该尝试对这些类进行调试(org.apache.http)并且看看它报告了什么。

可能值得深入研究为什么BadCredentialsException冒泡,因此我的意思是使用调试器来逐步浏览Spring Security OAuth2代码。

我之所以这么说,是因为根据我的经验,BadCredentialsException可能是由于底层的InvalidRequestException引起的,下面是违规行:

 throw new InvalidRequestException( "Possible CSRF detected - state parameter was required but no state could be found"); 

我在这里提出了一个单独的问题:

为什么AccessTokenRequest的PreservedState永远为空,并产生与CSRF相关的InvalidRequestException异常?

所以,根据你的情况,用新近推出的nginx代理,我只是想知道你是否可能没有看到一个误导性的例外。 也就是说,误导未被训练的oauth2和spring security oauth 2与CSRF是一个额外的复杂性来处理。

可能有点晚了,但我遇到了同样的事情。

我的安装程序是一个NGINX,通过使用Spring oAuth2执行一个运行的Spring Boot应用程序来进行SSL代理

nginx配置中解决这个问题

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; 

而这在你的spring application.yml中

  server.tomcat.remote_ip_header: X-Forwarded-For server.tomcat.protocol_header: X-Forwarded-Proto security.require_ssl: true 

来源: http : //docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html#howto-enable-https

现在,Spring检测到正确的URL,并且request.getRequestURL返回正确的URL,包括https://

  @Controller public class HomeController { @RequestMapping("/") @ResponseBody public String rootLandingPage(HttpServletRequest request) throws Exception { return "url: " + request.getRequestURL(); } }