I'm trying to get a Zuul reverse proxy setup with Spring Boot, Eureka, Zuul and Spring OAuth. Specifically, I'm trying to obtain an OAuth bearer token from our OAuth server that is behind Zuul. To do this, i need to make a POST request to the proxy endpoint that redirects to our OAuth server. This request is using the client_credentials grant type and thus am using BasicAuth to obtain the bearer token. I've verified that I can obtain the token by bypassing Zuul.
I been having trouble getting my expected results which are a reverse proxy that is OAuth aware but has no required security itself. I've tried a few different variations on configuration and cannot find the golden ticket.
Here is my Maven:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.cloud</groupId>
<artifactId>mycompany-cloud</artifactId>
<version>0.0.2-SNAPSHOT</version>
</parent>
<artifactId>mycompany-cloud-zuul-proxy</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I initially created a configuration that was just
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
@EnableOAuth2Sso
public class ZuulProxyApplication {
public static void main(final String[] args) {
SpringApplication.run(ZuulProxyApplication.class, args);
}
}
but this by default enabled basic auth security. I knew this because i would get CSRF erros on any POST request made. Setting security.enable-csrf=false
did not disable this (i found this odd). Setting security.basic.enabled=false
also did not disable any security also odd. I finally noticed the JavaDoc on @EnableOAuth2Sso
said that if no WebSecurityConfigurerAdapter
was provided then it would use a default. I tried adding the @EnableWebSecurity
to my configuration which should have added a WebSecurityConfigurerAdapter
but I was still getting CSRF errors on my POST requests. Maybe the default its using isnlt aware of SecurityProperties. So I ended up with this configuration:
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class ZuulProxyApplication {
public static void main(final String[] args) {
SpringApplication.run(ZuulProxyApplication.class, args);
}
@Configuration
@EnableOAuth2Sso
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
public void globalUserDetails(final AuthenticationManagerBuilder auth) throws Exception {
// add no users
auth.inMemoryAuthentication();
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
}
and the following properties:
spring:
application:
name: mycompany-cloud-zuul-proxy
index: 0
security:
oauth2:
client:
access-token-uri: http://mycompany-cloud-authorization-server/oauth/token
user-authorization-uri: http://mycompany-cloud-authorization-server/oauth/authorize
basic:
enabled: false
enable-csrf: false
sessions: stateless
server:
port: 9200
eureka:
client:
service-url:
defaultZone: http://localhost:9100/eureka/
And this was successful, it disabled the CSRF configuration and I was able to make POST requests to my services without receiving the CSRF error. However, now my OAuth server is rejecting the requests because the BasicAuth header is no longer on the request. It appears that Zuul is stripping the header. Am I misunderstanding that adding the @EnableOAuth2Sso
annotation makes the application OAuth aware and that it would allow means of accessing the configured OAuth server or does it simply apply to Bearer tokens? Is it normal to place your OAuth server behind the proxy or is that not an expected thing to do? I'm guessing that I'm missing some important knowledge and/or configuration that I have yet to comprehend from the documentation.
Any help here would be appreciated.