SSL / Proxy Error Using Spring Cloud OAuth2

I adapted the following OAauth2 Spring Cloud examples:

Authserver / SSO

The only change I made was to use JPA on the Authserver side to verify credentials from the database. Everything works well, with the exception of deploying it behind the nginx proxy. As used in the sample applications above, Spring Boot and embedded Tomcat are used. I also set proxy headers correctly:

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

Proxying HTTP works:

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

So far, so good, but I need to use SSL (obviously):

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

If I switch to SSL, I get 401 from my client application after the auth server redirects back from authorization. I grabbed HTTP traffic and it works:

The HTTP traffic for HTTP and HTTPS is exactly the same, except that the correct referent for the last request is set for HTTP (AFAIK, the referent is not checked during OAuth authentication, right?):

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 

Corresponding log message from the client application:

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

Any ideas why using proxies and SSL does not work? I am happy to share more code and / or magazine output!

Thanks!!!

+5
source share
3 answers

It looks unsuccessful when an SSO application tries to exchange an authentication code for a token. All the steps before this were browser redirection, this is the code on the SSO server that is trying to call the auth server. What do you use for SSL certificates on auth server? Do they sign a trusted party with a CA in the Java trust store? If this is not the case, it may be due to an error, because a BadCredentialsException is the end result of a failed HTTP request.

Another option is that there is no route directly from the SSO server to the address of the Auth server.

I believe this is ultimately the Apache Commons HttpClient code that will handle the request, so you should try debugging for these classes (org.apache.http) and see what it says.

+2
source

It might be worth taking a look at why the BadCredentialsException error occurs, and by that I mean going through the OAuth2 security code with your debugger.

The reason I say this is because, in my experience, a BadCredentialsException may be due to a base InvalidRequestException, with the following line breaking:

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

I raised a separate question related to the above:

Why does a PreservedState AccessTokenRequest always have a null value with the result of a CSRF-related InvalidRequestException?

So, from the point of view of your situation, with the recently introduced nginx proxy server, I'm just wondering if you can see an erroneous exception. That is, misleading raw in terms of oauth2 and Spring oauth 2 security with CSRF as added complexity to the solution.

0
source

Maybe a little late, but I came across the same thing.

My installation is NGINX, performing SSL proxying using a Spring boot application using Spring oAuth2 .

To solve this problem in nginx configuration

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

And this is in your spring .yml application

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

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

And now Spring detects the correct URL, and request.getRequestURL returns the right URL, including https: //

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

All Articles