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

时间:2015-05-11 09:51:58

标签: nginx spring-security spring-boot spring-security-oauth2 spring-cloud

我改编了以下OAauth2 Spring Cloud示例:

Authserver / SSO

我做的唯一更改是在Authserver端使用JPA来检查数据库中的凭据。一切都运行良好,除了在nginx代理后面部署它。如上面的示例应用程序中所使用的,使用Spring Boot和嵌入式Tomcat。我还正确配置了代理头:

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服务器从授权重定向后从我的客户端应用程序获得401。我捕获了HTTP流量,一切似乎都有效:

HTTP和HTTPS的HTTP流量完全相同,只是对于HTTP,为最后一个请求设置了适当的引用(AFAIK,在OAuth身份验证期间没有检查引用,对吗?):

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的任何想法都不起作用?我很高兴分享更多代码和/或日志输出!

感谢!!!

3 个答案:

答案 0 :(得分:2)

SSO应用尝试交换代码的auth代码时,看起来很失败。 之前的所有步骤都是浏览器重定向,这是尝试调用auth服务器的SSO服务器上的代码。 您在auth服务器上使用什么SSL证书?它们是否由Java信任库中具有CA的受信任方签署? 如果没有,这可能就是它失败的原因,因为BadCredentialsException是底层HTTP请求失败的最终结果。

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

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

答案 1 :(得分:1)

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

我的安装程序是NGINX使用Spring oAuth2进行SSL代理到正在运行的Spring Boot应用程序

要在 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检测到正确的网址, request.getRequestURL 现在返回正确的网址,包括https://

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

答案 2 :(得分:0)

可能值得仔细研究BadCredentialsException冒泡的原因,我的意思是用调试器逐步执行Spring Security OAuth2代码。

我之所以这么说是因为根据我的经验,BadCredentialsException可能是由于潜在的InvalidRequestException,以下是违规行:

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

我在这里提出了与上述有关的单独问题:

Why is AccessTokenRequest's PreservedState perpetually null with a resultant CSRF related InvalidRequestException?

所以,就你的情况而言,使用新推出的nginx代理,我只是想知道你是否可能没有看到一个误导性的异常。也就是说,使用CSRF作为额外的复杂性来处理oauth2和spring security oauth 2方面的未经训练的误导。