spring-security - 使用 Spring boot、Eureka、Zuul、Spring Oauth 创建 OAuth 安全微服务的问题

标签 spring-security spring-boot spring-cloud spring-oauth2

我正在尝试使用 Spring Boot、Eureka、Zuul 和 Spring OAuth 设置 Zuul 反向代理。具体来说,我试图从 Zuul 背后的 OAuth 服务器获取 OAuth 不记名 token 。为此,我需要向重定向到我们的 OAuth 服务器的代理端点发出 POST 请求。此请求使用 client_credentials 授权类型,因此使用 BasicAuth 来获取不记名 token 。我已经验证我可以通过绕过 Zuul 来获取 token 。

我在获得预期结果时遇到了麻烦,这是一个支持 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);
  }
}

但这默认启用了基本身份验证安全性。我知道这一点,因为我会在任何 POST 请求中得到 CSRF 错误。设置 security.enable-csrf=false没有禁用它(我发现这很奇怪)。设置 security.basic.enabled=false也没有禁用任何安全也奇。我终于在 @EnableOAuth2Sso 上注意到了 JavaDoc说如果没有WebSecurityConfigurerAdapter提供然后它将使用默认值。我尝试添加 @EnableWebSecurity在我的配置中应该添加了 WebSecurityConfigurerAdapter但我的 POST 请求仍然收到 CSRF 错误。也许它的默认使用不知道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 header 。看来 Zuul 正在剥离标题。我是否误解添加 @EnableOAuth2Sso注释使应用程序知道 OAuth 并且它允许访问配置的 OAuth 服务器的方法还是仅适用于不记名 token ?将您的 OAuth 服务器放在代理后面是否正常,或者这不是预期的事情?我猜我遗漏了一些我尚未从文档中理解的重要知识和/或配置。

任何帮助在这里将不胜感激。

最佳答案

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



默认情况下,Spring cloud Zuul 实现会出于安全目的剥离一些 header (请参阅 Cookies and sensitive headers documentation )

因此,自 Spring cloud netflix 1.1 之后的标题 Cookie, Set-Cookie, Authorization被认为是合理的标题

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



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

我个人创建了一个 POC 用于代理背后的授权 https://github.com/kakawait/uaa-behind-zuul-sample这可能(或不)帮助你。

关于spring-security - 使用 Spring boot、Eureka、Zuul、Spring Oauth 创建 OAuth 安全微服务的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38311521/

相关文章:

java - 如何使用对象有效负载而不是来自 MessageCollector 的字符串接收 GenericMessage

java - Spring Security OAuth2授权流程

spring - 自定义 AuthenticationFailureHandler 中的 Flash 属性

Spring Boot 多项目的 Gradle Build Fail

Spring boot微服务的MySQL配置

spring - 如何为 Spring Cloud 配置设置日志记录级别

java - 如何使用 ActiveMQ 设置 Spring Cloud Bus?

angular - spring boot angular csrf token 握手错误

java - 当第二个过滤器尝试写入响应流时,2 个链接的 AbstractAuthenticationProcessingFilter 导致 302 重定向

java - Spring Boot requestDataValueProcessor Bean 定义冲突