Spring security 使用Spring boot、Eureka、Zuul、Spring OAuth创建OAuth安全微服务时出现的问题

Spring security 使用Spring boot、Eureka、Zuul、Spring OAuth创建OAuth安全微服务时出现的问题,spring-security,spring-boot,spring-cloud,spring-oauth2,Spring Security,Spring Boot,Spring Cloud,Spring Oauth2,我正在尝试使用SpringBoot、Eureka、Zuul和SpringOAuth来设置Zuul反向代理。具体地说,我正在尝试从Zuul后面的OAuth服务器获取OAuth承载令牌。为此,我需要向代理端点发出POST请求,该端点将重定向到OAuth服务器。此请求使用客户机_凭证授予类型,因此我使用BasicAuth获取承载令牌。我已经验证了我可以绕过Zuul获得令牌 我一直很难得到预期的结果,这是一个支持OAuth但本身没有必要安全性的反向代理。我尝试了几种不同的配置,但找不到最佳配置 这是我的

我正在尝试使用SpringBoot、Eureka、Zuul和SpringOAuth来设置Zuul反向代理。具体地说,我正在尝试从Zuul后面的OAuth服务器获取OAuth承载令牌。为此,我需要向代理端点发出POST请求,该端点将重定向到OAuth服务器。此请求使用客户机_凭证授予类型,因此我使用BasicAuth获取承载令牌。我已经验证了我可以绕过Zuul获得令牌

我一直很难得到预期的结果,这是一个支持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>
但这在默认情况下启用了基本的身份验证安全性。我知道这一点,因为我会得到CSRF错误的任何职位要求。设置
security.enable csrf=false
没有禁用此功能(我发现这很奇怪)。设置
security.basic.enabled=false也没有禁用任何安全性。我终于注意到
@enableAuth2sso
上的JavaDoc说,如果没有提供
WebSecurityConfigureAdapter
,那么它将使用默认值。我尝试将
@EnableWebSecurity
添加到我的配置中,该配置本应添加
websecurityConfigureAdapter
,但我的POST请求中仍然出现CSRF错误。可能默认情况下,它使用的是NLT感知SecurityProperty。因此,我最终采用了以下配置:

@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配置,我能够在没有收到CSRF错误的情况下向我的服务发出POST请求。但是,现在我的OAuth服务器拒绝了这些请求,因为BasicAuth头不再在请求中。Zuul似乎正在剥离收割台。我是否误解了添加
@enableAuth2sso
注释会使应用程序OAuth意识到,它将允许访问已配置的OAuth服务器,或者它只是应用于承载令牌?将OAuth服务器放在代理之后是正常的还是不应该这样做?我猜我遗漏了一些重要的知识和/或配置,这些知识和/或配置我还没有从文档中理解

这里的任何帮助都将不胜感激

但是,现在我的OAuth服务器拒绝了这些请求,因为BasicAuth头不再在请求中

默认情况下,SpringCloudZuul实现会出于安全目的剥离一些头文件(请参阅)

因此,由于Spring cloud netflix 1.1遵循的标题
Cookie、Set Cookie、Authorization
被认为是合理的标题

将OAuth服务器放在代理之后是正常的还是不应该这样做

springcloud在默认情况下基本上没有设计为在代理(Zuul)后面有授权服务器(或OAuth服务器)。在大多数示例中,文档和授权服务器位于代理之外


我个人为代理背后的授权创建了一个POC,它可能(也可能不会)帮助您。

这一切似乎都是为基于用户的oauth量身定制的。我们主要还需要支持授权类型的客户端\ U凭据,并最终支持所有其他授权类型。根据您提供的一些代码,我已经在工作,这些服务将接收到的承载令牌传递到它调用的其他服务上,但是现在我正在尝试让zuul代理也这样做。我开始觉得为@enableAuthSSO构建的所有东西都是根据实际用户参与的OAuth方案定制的(例如,不是客户端凭据)。是这样吗?根据我对
@enableAuthSSO
的理解,您不能使用
客户端凭据,因为SSO是为用户和浏览器设计的。如果某些路由需要与客户端凭据一起使用,只需删除此路由上的SSO即可。但若你们的路线应该支持两者,我认为目前还不可能,你们可以直接和SpringGuysok在gitter上公开问题或提问。很好地验证了我的假设。我找不到任何地方说它只针对基于用户的oauth。我认为SSO也应该能够用于基于机器的身份验证以及基于用户的身份验证。我所期望的工作方式是,盲目地将承载令牌传递(或预先验证它们)到被调用的后端服务,并根据所使用的授权类型将用户路由到登录/授权页面到oauth服务器。我不认为这会比这更多。我最终让授权服务器(主要)在Zuul后面工作。然而,由于出现了一些问题,我最终离开了祖尔。一个问题是,授权服务器将重定向发送回登录页面以进行基于用户的身份验证。在构建重定向URL时,此重定向会考虑正常的X-Forwarded-*头,但不会考虑Zuul添加的X-Forwarded-Path头,因为大多数端点都在特定路径(*->*)后面代理Zuul不是现成的ReverseProxy。您是否在auth服务器上使用了
ForwardedHeaderFilter
?我个人对这种架构的路径和转发头没有问题。
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/