春云持有人头通过

时间:2017-11-01 06:42:52

标签: java spring spring-cloud netflix-zuul

这似乎是一个非常常见的问题,并且有一个简单的答案,但实施记录的解决方案并不适合我。

我有一个zuul代理/网关,用于所有传入的请求,然后将这些请求转发到不同的微服务。每个传入请求都在标头中设置了正确的承载令牌(这在前端设置和验证(来自okta)并确认它在跳过Zuul并直接转到服务时有效),我只需要将其传递给微型服务。

EdgeServiceApplication

@EnableHystrix
@EnableZuulProxy
@EnableEurekaClient
@EnableOAuth2Sso
@SpringBootApplication
public class EdgeServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(EdgeServiceApplication.class, args);
    }
}

Zuul application.yml

server:
  port: 8080

logging:
  level:
    root: INFO
    org.springframework.web: INFO
    org.springframework.security: INFO

zuul:
  sensitiveHeaders: Cookie,Set-Cookie,Authorization

在我的微服务上,

@EnableEurekaClient
@SpringBootApplication
@EnableResourceServer
public class InstanceServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(InstanceServiceApplication.class, args);
    }
}

当我尝试通过Zuul向微服务发送请求时,我收到401响应。

将以下bean添加到我的微服务中时,我可以看到当来自Zuul的请求时没有设置Authorization标头,但是我可以在直接调用时看到它设置。

@Bean
public FilterRegistrationBean requestDumperFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    Filter requestDumperFilter = new RequestDumperFilter();
    registration.setFilter(requestDumperFilter);
    registration.addUrlPatterns("/*");
    return registration;
}

我是Spring的新手,所以只是希望我在某个地方的.yml文件中遗漏了一些东西?

当前依赖关系

buildscript {
ext {
    springBootVersion = '1.5.8.RELEASE'
}
repositories {
    mavenCentral()
}
dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    classpath('io.spring.gradle:dependency-management-plugin:0.5.4.RELEASE')
}
}

dependencies {
    compile('org.springframework.cloud:spring-cloud-starter-eureka')
    compile('org.springframework.cloud:spring-cloud-starter-config')
    compile('org.springframework.cloud:spring-cloud-starter-zuul')
    compile('org.springframework.cloud:spring-cloud-starter-ribbon')

    compile('org.springframework.boot:spring-boot-starter')
    compile('org.springframework.boot:spring-boot-starter-web')

    compile('org.springframework.boot:spring-boot-starter-data-rest')
    compile("org.springframework.boot:spring-boot-starter-actuator")
    compile('org.springframework.boot:spring-boot-starter-websocket')

    compile('org.springframework.security.oauth:spring-security-oauth2:2.2.0.RELEASE')
    compile('org.springframework.cloud:spring-cloud-security:1.2.1.RELEASE')
} 

更新

根据建议改变我的申请后,我仍然在任何请求上点击401。

2017-11-02 11:03:05.697 ERROR 7139 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException: 401 null] with root cause

org.springframework.web.client.HttpClientErrorException: 401 null
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:78) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)

我开始认为其他地方出了问题。我有一个看起来像的SecurityConfig类(我知道生产不安全)

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().antMatcher("/**")
                .authorizeRequests()
                .anyRequest().permitAll();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(ImmutableList.of("*"));
        configuration.setAllowedMethods(ImmutableList.of("*"));
        configuration.setAllowedHeaders(ImmutableList.of("*"));
        configuration.setAllowCredentials(true);

        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

        source.registerCorsConfiguration("/**", configuration);

        return source;
    }
}

我的微服务上唯一的安全配置是

@EnableEurekaClient
@SpringBootApplication
@EnableResourceServer
public class InstanceServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(InstanceServiceApplication.class, args);
    }

    @EnableGlobalMethodSecurity(prePostEnabled = true)
    protected static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration {
        @Override
        protected MethodSecurityExpressionHandler createExpressionHandler() {
            return new OAuth2MethodSecurityExpressionHandler();
        }
    }

    @Bean
    protected ResourceServerConfigurerAdapter resourceServerConfigurerAdapter() {
        return new ResourceServerConfigurerAdapter() {
            @Override
            public void configure(HttpSecurity http) throws Exception {
                http.authorizeRequests()
                        .anyRequest().authenticated();
            }
        };
    }

    @Bean
    public FilterRegistrationBean requestDumperFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        Filter requestDumperFilter = new RequestDumperFilter();
        registration.setFilter(requestDumperFilter);
        registration.addUrlPatterns("/*");
        return registration;
    }
}

更新#2:

注销请求标头,仍然没有授权

2017-11-02 11:25:24.133  INFO 7381 --- [nio-8080-exec-2] s.s.e.s.c.LoggingRequestInterceptor      : URI         : http://instance-service
2017-11-02 11:25:24.133  INFO 7381 --- [nio-8080-exec-2] s.s.e.s.c.LoggingRequestInterceptor      : Method      : GET
2017-11-02 11:25:24.133  INFO 7381 --- [nio-8080-exec-2] s.s.e.s.c.LoggingRequestInterceptor      : Headers     : {Accept=[text/plain, application/json, application/*+json, */*], Content-Length=[0]}
2017-11-02 11:25:24.133  INFO 7381 --- [nio-8080-exec-2] s.s.e.s.c.LoggingRequestInterceptor      : Request body: 

更新#3:

我已经制作了一个快速示例应用程序,它也剥离了身份验证标题... https://github.com/peavers/zuul-oauth-passthrough - 希望有人能够发现我做错了什么。

1 个答案:

答案 0 :(得分:2)

来自official documentation

  

sensitiveHeaders是黑名单,默认不为空,所以   让Zuul发送所有标题(除了“忽略”标题)   必须明确地将其设置为空列表。如果你这是必要的   想要将cookie或授权标题传递给你的后端。

所以-•-•反过来工作。它们可以防止将标头下放到您的后端。您应该将其从列表中删除,而不是将“授权”标题添加到列表中:

sensitiveHeaders

或者像这样(如果你因为某些原因需要将Cookie缩小到你的后端(我希望你不这样做)):

zuul:
  sensitiveHeaders: Cookie,Set-Cookie