聊聊spring cloud gateway的SecureHeadersGatewayFilter
序
本文主要研究下spring cloud gateway的SecureHeadersGatewayFilter
GatewayAutoConfiguration
@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
@AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {
//......
@Bean
public SecureHeadersGatewayFilterFactory secureHeadersGatewayFilterFactory(SecureHeadersProperties properties) {
return new SecureHeadersGatewayFilterFactory(properties);
}
//......
}
SecureHeadersProperties
配置项
{
"sourceType": "org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties",
"defaultValue": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'",
"name": "spring.cloud.gateway.filter.secure-headers.content-security-policy",
"type": "java.lang.String"
},
{
"sourceType": "org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties",
"defaultValue": "nosniff",
"name": "spring.cloud.gateway.filter.secure-headers.content-type-options",
"type": "java.lang.String"
},
{
"sourceType": "org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties",
"defaultValue": "noopen",
"name": "spring.cloud.gateway.filter.secure-headers.download-options",
"type": "java.lang.String"
},
{
"sourceType": "org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties",
"defaultValue": "DENY",
"name": "spring.cloud.gateway.filter.secure-headers.frame-options",
"type": "java.lang.String"
},
{
"sourceType": "org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties",
"defaultValue": "none",
"name": "spring.cloud.gateway.filter.secure-headers.permitted-cross-domain-policies",
"type": "java.lang.String"
},
{
"sourceType": "org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties",
"defaultValue": "no-referrer",
"name": "spring.cloud.gateway.filter.secure-headers.referrer-policy",
"type": "java.lang.String"
},
{
"sourceType": "org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties",
"defaultValue": "max-age=631138519",
"name": "spring.cloud.gateway.filter.secure-headers.strict-transport-security",
"type": "java.lang.String"
},
{
"sourceType": "org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties",
"defaultValue": "1 ; mode=block",
"name": "spring.cloud.gateway.filter.secure-headers.xss-protection-header",
"type": "java.lang.String"
}
实体类
spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/filter/factory/SecureHeadersProperties.java
@ConfigurationProperties("spring.cloud.gateway.filter.secure-headers")
public class SecureHeadersProperties {
public static final String X_XSS_PROTECTION_HEADER_DEFAULT = "1 ; mode=block";
public static final String STRICT_TRANSPORT_SECURITY_HEADER_DEFAULT = "max-age=631138519"; //; includeSubDomains preload")
public static final String X_FRAME_OPTIONS_HEADER_DEFAULT = "DENY"; //SAMEORIGIN = ALLOW-FROM
public static final String X_CONTENT_TYPE_OPTIONS_HEADER_DEFAULT = "nosniff";
public static final String REFERRER_POLICY_HEADER_DEFAULT = "no-referrer"; //no-referrer-when-downgrade = origin = origin-when-cross-origin = same-origin = strict-origin = strict-origin-when-cross-origin = unsafe-url
public static final String CONTENT_SECURITY_POLICY_HEADER_DEFAULT = "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'";
public static final String X_DOWNLOAD_OPTIONS_HEADER_DEFAULT = "noopen";
public static final String X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER_DEFAULT = "none";
private String xssProtectionHeader = X_XSS_PROTECTION_HEADER_DEFAULT;
private String strictTransportSecurity = STRICT_TRANSPORT_SECURITY_HEADER_DEFAULT;
private String frameOptions = X_FRAME_OPTIONS_HEADER_DEFAULT;
private String contentTypeOptions = X_CONTENT_TYPE_OPTIONS_HEADER_DEFAULT;
private String referrerPolicy = REFERRER_POLICY_HEADER_DEFAULT;
private String contentSecurityPolicy = CONTENT_SECURITY_POLICY_HEADER_DEFAULT;
private String downloadOptions = X_DOWNLOAD_OPTIONS_HEADER_DEFAULT;
private String permittedCrossDomainPolicies = X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER_DEFAULT;
//......
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("SecureHeadersProperties{");
sb.append("xssProtectionHeader='").append(xssProtectionHeader).append('\'');
sb.append(", strictTransportSecurity='").append(strictTransportSecurity).append('\'');
sb.append(", frameOptions='").append(frameOptions).append('\'');
sb.append(", contentTypeOptions='").append(contentTypeOptions).append('\'');
sb.append(", referrerPolicy='").append(referrerPolicy).append('\'');
sb.append(", contentSecurityPolicy='").append(contentSecurityPolicy).append('\'');
sb.append(", downloadOptions='").append(downloadOptions).append('\'');
sb.append(", permittedCrossDomainPolicies='").append(permittedCrossDomainPolicies).append('\'');
sb.append('}');
return sb.toString();
}
}
SecureHeadersGatewayFilterFactory
spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/springframework/cloud/gateway/filter/factory/SecureHeadersGatewayFilterFactory.java
/**
* https://blog.appcanary.com/2017/http-security-headers.html
* @author Spencer Gibb
*/
public class SecureHeadersGatewayFilterFactory extends AbstractGatewayFilterFactory {
public static final String X_XSS_PROTECTION_HEADER = "X-Xss-Protection";
public static final String STRICT_TRANSPORT_SECURITY_HEADER = "Strict-Transport-Security";
public static final String X_FRAME_OPTIONS_HEADER = "X-Frame-Options";
public static final String X_CONTENT_TYPE_OPTIONS_HEADER = "X-Content-Type-Options";
public static final String REFERRER_POLICY_HEADER = "Referrer-Policy";
public static final String CONTENT_SECURITY_POLICY_HEADER = "Content-Security-Policy";
public static final String X_DOWNLOAD_OPTIONS_HEADER = "X-Download-Options";
public static final String X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER = "X-Permitted-Cross-Domain-Policies";
private final SecureHeadersProperties properties;
public SecureHeadersGatewayFilterFactory(SecureHeadersProperties properties) {
this.properties = properties;
}
@Override
public GatewayFilter apply(Object config) {
//TODO: allow args to override properties
return (exchange, chain) -> {
HttpHeaders headers = exchange.getResponse().getHeaders();
//TODO: allow header to be disabled
headers.add(X_XSS_PROTECTION_HEADER, properties.getXssProtectionHeader());
headers.add(STRICT_TRANSPORT_SECURITY_HEADER, properties.getStrictTransportSecurity());
headers.add(X_FRAME_OPTIONS_HEADER, properties.getFrameOptions());
headers.add(X_CONTENT_TYPE_OPTIONS_HEADER, properties.getContentTypeOptions());
headers.add(REFERRER_POLICY_HEADER, properties.getReferrerPolicy());
headers.add(CONTENT_SECURITY_POLICY_HEADER, properties.getContentSecurityPolicy());
headers.add(X_DOWNLOAD_OPTIONS_HEADER, properties.getDownloadOptions());
headers.add(X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER, properties.getPermittedCrossDomainPolicies());
return chain.filter(exchange);
};
}
}
可以看到该filter往response的header添加一系列的security相关的header
小结
SecureHeadersGatewayFilter往response添加了如下header
- X-Xss-Protection
spring.cloud.gateway.filter.secure-headers.xss-protection-header=1 ; mode=block
- Strict-Transport-Security
spring.cloud.gateway.filter.secure-headers.strict-transport-security=max-age=631138519
- X-Frame-Options
spring.cloud.gateway.filter.secure-headers.frame-options=DENY
- X-Content-Type-Options
spring.cloud.gateway.filter.secure-headers.content-type-options=nosniff
- Referrer-Policy
spring.cloud.gateway.filter.secure-headers.referrer-policy=no-referrer
- Content-Security-Policy
spring.cloud.gateway.filter.secure-headers.content-security-policy=default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
- X-Download-Options
spring.cloud.gateway.filter.secure-headers.download-options=noopen
- X-Permitted-Cross-Domain-Policies
spring.cloud.gateway.filter.secure-headers.permitted-cross-domain-policies=none
doc
code-craft
spring boot , docker and so on 欢迎关注微信公众号: geek_luandun
被 1 篇内容引用
推荐阅读
2022年终总结
最近两年开始陷入颓废中,博客也写的越来越少了。究其原因,主要还是陷入了职业倦怠期,最近一次跳槽感觉颇为失败,但是碍于给的薪资高,为了五斗米折腰,又加上最近行情不好,想要往外跳也跳不了,就这样子一直...
codecraft阅读 711
feign调用把CPU吃满了?这个锅HttpMessageConverters来背
SpringEncoder / SpringDecoder 在每次编码 / 解码时都会调用 ObjectFactory<HttpMessageConverters>.getObject()).getConverters() 获取 HttpMessageConverters。
开翻挖掘机赞 1阅读 470
Spring Cloud中MyBatis-Plus动态数据源刷新问题
在使用MyBatis-Plus的DynamicRoutingDataSource时遇到的问题,当我在配置中心动态增加或者删除了一个数据源,他并不会自动同步最新的数据源,导致我用DynamicDataSourceContextHolder.push(ds)方法的时候拿不到刚...
Pursuer丶阅读 690
这些不知道,别说你熟悉 Nacos,深度源码解析!
大家好,这篇文章跟大家聊下 SpringCloudAlibaba 中的微服务组件 Nacos。Nacos 既能做注册中心,又能做配置中心,这篇文章主要来聊下做配置中心时 client 端的一些设计,主要从源码层面进行分析,相信看完这篇文...
yanhom赞 1阅读 292
Spring Cloud OpenFeign调用流程
上一节给大家分享了Spring Cloud OpenFeign的启动流程,接下来给大家分享一下调用流程。话不多说,咱们直接开始。视频:[链接]调用流程xxxFeignClient → feign.ReflectiveFeign.FeignInvocationHandler#invoke→ f...
冯文议阅读 538
【Spring Cloud】Feign调用异常触发降级后如何捕获异常
在Spring Cloud的微服务架构中,通常微服务之间通过feign/openfeign来进行http调用,并且启用hystrix并配置降级策略fallback,可以在http调用异常时触发降级,代码如下
kamier阅读 508
Nacos 中的配置文件如何实现加密传输
小伙伴们知道,Spring Cloud Config 很早就提供了配置文件的加解密功能,并且支持对称加密和非对称加密两种不同的模式。Nacos 作为分布式配置中心+服务注册中心的合体,在配置文件加密这块一直差点意思,不过好在...
Java架构师阅读 353
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。