简体   繁体   中英

Issues creating OAuth secured Microservices using Spring boot, Eureka, Zuul, Spring Oauth

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.

However, now my OAuth server is rejecting the requests because the BasicAuth header is no longer on the request

By default Spring cloud Zuul implementation strips some headers for security purpose (see Cookies and sensitive headers documentation )

Thus since Spring cloud netflix 1.1 following headers Cookie, Set-Cookie, Authorization are considered as sensible headers

Is it normal to place your OAuth server behind the proxy or is that not an expected thing to do?

Spring cloud is basically not designed by default to have Authorization server (or OAuth server) behind proxy (Zuul). In most example and documention Authorization server is outside proxy.

I personally created a POC for Authorization behind Proxy https://github.com/kakawait/uaa-behind-zuul-sample that may (or not) help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM