这似乎是一个非常常见的问题,并且有一个简单的答案,但是实现文档化的解决方案对我来说是行不通的。
我对所有传入请求都有一个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的请求时没有授权头集,但是我可以在直接调用时看到它的设置。
@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 --希望有人能发现我做错了什么。
发布于 2017-11-01 09:45:26
来自正式文件:
sensitiveHeaders是一个黑名单,默认不是空的,因此要使Zuul发送所有标题(除了“忽略的”标题),您必须显式地将其设置为空列表。如果您想将cookie或授权头传递到后端,这是必要的。
所以sensitiveHeaders的工作方式正好相反。它们防止标题被降到后端。与其向列表中添加授权头,不如将其从列表中删除,如下所示:
zuul:
sensitiveHeaders: Cookie,Set-Cookie或者像这样(如果您出于某些原因需要将Cookies下载到后端(我希望您不要):
zuul:
sensitiveHeaders:https://stackoverflow.com/questions/47049537
复制相似问题