Проблемы при создании микросервисов с защитой OAuth с использованием Spring boot, Eureka, Zuul, Spring Oauth

Я пытаюсь настроить обратный прокси-сервер Zuul с помощью Spring Boot, Eureka, Zuul и Spring OAuth. В частности, я пытаюсь получить токен носителя OAuth с нашего сервера OAuth, который находится за Zuul. Для этого мне нужно сделать запрос POST к конечной точке прокси, которая перенаправляет на наш сервер OAuth. В этом запросе используется тип предоставления client_credentials, поэтому я использую BasicAuth для получения токена носителя. Я подтвердил, что могу получить токен, минуя Зуула.

У меня возникли проблемы с получением ожидаемых результатов, которые представляют собой обратный прокси-сервер, который поддерживает OAuth, но не имеет необходимой безопасности. Я пробовал несколько разных вариантов конфигурации и не могу найти золотой билет.

Вот мой 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>

Изначально я создал конфигурацию, которая была просто

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
@EnableOAuth2Sso
public class ZuulProxyApplication {
  public static void main(final String[] args) {
    SpringApplication.run(ZuulProxyApplication.class, args);
  }
}

но по умолчанию включена базовая безопасность аутентификации. Я знал это, потому что получал ошибки CSRF при любом запросе POST. Установка security.enable-csrf=false не отключила это (я нашел это странным). Установка security.basic.enabled=false тоже не отключила никакой безопасности, тоже странно. Наконец я заметил, что JavaDoc на @EnableOAuth2Sso говорит, что если WebSecurityConfigurerAdapter не был предоставлен, он будет использовать значение по умолчанию. Я попытался добавить @EnableWebSecurity в свою конфигурацию, которая должна была добавить WebSecurityConfigurerAdapter, но я все еще получал ошибки CSRF в моих запросах POST. Возможно, его использование по умолчанию не знает SecurityProperties. Итак, я получил такую ​​конфигурацию:

@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();
    }

  }
}

и следующие свойства:

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/

И это было успешно, он отключил конфигурацию CSRF, и я смог отправлять запросы POST к своим службам, не получая ошибки CSRF. Однако теперь мой сервер OAuth отклоняет запросы, потому что заголовок BasicAuth больше не находится в запросе. Похоже, что Зуул срывает заголовок. Я неправильно понимаю, что добавление аннотации @EnableOAuth2Sso сообщает приложению OAuth и что это позволяет получить доступ к настроенному серверу OAuth, или это просто применимо к токенам носителя? Нормально ли размещать сервер OAuth за прокси-сервером или этого не следует делать? Я предполагаю, что мне не хватает некоторых важных знаний и / или конфигурации, которые мне еще предстоит понять из документации.

Любая помощь здесь будет оценена по достоинству.


person loesak    schedule 11.07.2016    source источник


Ответы (1)


Однако теперь мой сервер OAuth отклоняет запросы, потому что заголовок BasicAuth больше не находится в запросе.

По умолчанию реализация Spring cloud Zuul удаляет некоторые заголовки в целях безопасности (см. Документация по файлам cookie и конфиденциальным заголовкам)

Таким образом, начиная с Spring cloud netflix 1.1 следующие заголовки Cookie, Set-Cookie, Authorization считаются разумными заголовками

Нормально ли размещать сервер OAuth за прокси-сервером или этого не следует делать?

Spring Cloud по умолчанию не предусматривает наличие сервера авторизации (или сервера OAuth) за прокси-сервером (Zuul). В большинстве примеров и документации сервер авторизации находится за пределами прокси.

Я лично создал POC для авторизации за прокси https://github.com/kakawait/uaa-behind-zuul-sample, которые могут (или нет) вам помочь.

person Kakawait    schedule 14.07.2016
comment
похоже, что все это адаптировано к пользовательскому протоколу oauth. В первую очередь нам необходимо также поддерживать тип предоставления client_credentials и, в конечном итоге, все другие типы грантов. У меня есть работающие на основе вашего предоставленного кода службы, передающие полученный токен-носитель другим службам, которые он вызывает, но теперь я пытаюсь заставить прокси-сервер zuul делать то же самое. Я начинаю чувствовать, что все, что создано для @EnableOAuthSso, было адаптировано к схемам OAuth, в которых задействован реальный пользователь (например, не client_credentials). Так ли это? - person loesak; 20.07.2016
comment
Насколько я понимаю, с @EnableOauthSso вы не можете использовать client_credentials, потому что система единого входа разработана для человека и браузера. Если некоторые маршруты необходимо использовать с client_credentials, просто удалите SSO на этом маршруте. Но если ваш маршрут должен поддерживать оба, я думаю, в настоящее время это невозможно, вы можете открыть проблему или спросить gitter напрямую с парнями из Spring. - person Kakawait; 21.07.2016
comment
Ok. хорошо, чтобы подтвердить мои предположения. Я не мог найти нигде, где говорилось, что это только для пользователя oauth. Я бы подумал, что SSO также должна работать как для машинной базы, так и для аутентификации на основе пользователей. То, как я ожидал, что это сработает, будет заключаться в том, чтобы либо слепо передавать токены-носители (или предварительно проверять их) вызываемой серверной службе, либо оставлять маршрутизацию пользователя на страницы входа / авторизации на сервер oauth на основе тип используемого гранта. Не думаю, что это будет намного больше. - person loesak; 21.07.2016
comment
В итоге я заставил сервер авторизации работать (в основном) за Zuul. Однако в итоге я удалился из-за Зуула, потому что возникли некоторые проблемы. Одна из проблем заключалась в том, что сервер авторизации отправляет обратно перенаправления на страницу входа для аутентификации на основе пользователя. Это перенаправление учитывает обычные заголовки X-Forwarded- * при создании этого URL-адреса перенаправления, но не учитывает заголовок X-Forwarded-Path, который добавляет Zuul, потому что большинство конечных точек проксируются за определенным путем (zuul / uaa / v1 * - ›auth *) и Zuul не является обратным прокси из коробки. - person loesak; 05.10.2016
comment
Вы использовали ForwardedHeaderFilter на сервере аутентификации? У меня лично нет проблем с заголовком path и forward с такой архитектурой. - person Kakawait; 05.10.2016
comment
я сделал, он правильно использовал все заголовки x-forwarded- *, кроме пути один - person loesak; 17.10.2016
comment
мои извенения. я неправильно прочитал ваш комментарий. думал, что вы имеете в виду включенную конфигурацию весенней загрузки use-forwarded-headers. Я не думаю, что использую этот конкретный фильтр, если он не настроен автоматически, что не похоже на него. Я бы подозревал, что use-forwarded-headers сделали бы это автоматически (новая функция?), Но похоже, что он просто использовался для настройки базового сервера (клапан tomcat в моем случае), который, я не думаю, знает о x-forwarded- приставка. Я изучу использование фильтра и посмотрю, решит ли это мою проблему. - person loesak; 17.10.2016
comment
При весенней загрузке возникает проблема с добавлением фильтра по умолчанию, но разработчики по какой-то причине, упомянутые в этой проблеме, отказываются это делать. Реф. Номера у меня нет, но вы легко его найдете. - person Kakawait; 17.10.2016
comment
есть ли какое-нибудь решение, чтобы заставить zuul переписывать / добавлять пути файлов cookie? Скажите, что при использовании сервера oauth за zuul путь для файла cookie сеанса изменяется, чтобы добавить путь, отображаемый zuul? - person loesak; 26.10.2016