Http响应头处理
Spring Security 支持一些响应头信息,显示支持的Http响应头主要有如下几种:
* Cache-Control: no-cache, no-store, max-age=0, must-revalidate
* Pragma: no-cache
* Expires: 0
* X-Content-Type-Options: nosniff
* Strict-Transport-Security: max-age=31536000 ; includeSubDomains
* X-Frame-Options: DENY
* X-XSS-Protection: 1; mode=block
在HeaderWriterFilter中添加,默认情况下,该过滤器会添加到Spring Security过滤器链中,HeaderWriterFilter是通过HeadersConfigurer进行配置
private List<HeaderWriter> getHeaderWriters() {
List<HeaderWriter> writers = new ArrayList<>();
addIfNotNull(writers, contentTypeOptions.writer);
addIfNotNull(writers, xssProtection.writer);
addIfNotNull(writers, cacheControl.writer);
addIfNotNull(writers, hsts.writer);
addIfNotNull(writers, frameOptions.writer);
addIfNotNull(writers, hpkp.writer);
addIfNotNull(writers, contentSecurityPolicy.writer);
addIfNotNull(writers, referrerPolicy.writer);
addIfNotNull(writers, featurePolicy.writer);
writers.addAll(headerWriters);
return writers;
}
默认前五个不为null
contentTypeOptions.writer:负责处理X-Content-Type-Options响应头
xssProtection.writer:负责X-XSS-Protection响应头
cacheControl.writer:负责处理Cache-Control Pragma Expires的响应头
hsts.writer:负载处理Strict-Transport-Security响应头
frameOptions.writer:负责处理X-Frame-Options响应头
缓存控制
和缓存控制相关响应头有三个
- Cache-Control: no-cache, no-store, max-age=0, must-revalidate
- Pragma: no-cache
- Expires: 0
Cache-Control
HTTP /1,1引入,无论请求头还是响应头都支持该字段,no-store表示不作任何缓存,每次请求都会从服务端完整地下载内容,no-cache表示缓存但需要重新验证,数据虽然缓存在客户端,但是当需要使用该数据时,还是会向服务端发送请求,服务端则验证请求中所描述的缓存是否过期,如果没有过期,则返回304,客户端使用缓存;如果已经过期,则返回最新数据。
max-age表示缓存的有效期,单位为秒,must-revalidate表示当缓存在使用一个陈旧的资源时,必须先验证它的状态,已过期的将不被使用。
Pragma
和Cache-Control类似,兼容HTTP/1.0
Expires
Expires指在指定日期之后,缓存过期,如果日期为0,表示缓存已经过期。
Spring Security默认就是不做任何缓存,对于放行的url会缓存。
要想经过过滤器的请求也开启缓存,需要禁用掉Security的cacheControl .headers().cacheControl().disable()
X-Content-Type-Options
X-Content-Type-Options: nosniff 表示禁用客户端的MIME类型的嗅探,即服务端告诉客户端对于MIME类型的设置没有任何问题,当Content-Type类型值缺失时,不需要客户端对响应报文进行自我解析。
如果不想禁用MIME嗅探,配置 .headers().contentTypeOptions().disable()
Strict-Transport-Security
Strict-Transport-Security用来指定当前客户端只能通过HTTPS访问服务端,而不能通过HTTP访问。
可以通过java自带的keytool来生成HTTPS证书。
X-Frame-Options
X-Frame-Options响应头用来告诉浏览器是否允许一个页面在<frame> <iframe> <embed> <object>
中展现,通过该响应头可以确保网站没有被嵌入到其他站点里面,进而避免发生单击劫持。
- deny 表示该页面不允许在frame中展现。
- sameorigin:该页面可以在相同域名页面的frame中展示。
- allow-from uri:表示该页面可以在指定来源的frame中展示。
所谓单击劫持是指攻击者被劫持的页面放在一个iframe标签中,设置该iframe不可见,然后将iframe标签覆盖在另一个页面上,诱使用户在该页面上进行操作,通过调制iframe页面位置,使用户单击iframe页面的按钮。
X-XSS-Protection
X-XSS-Protection响应头告诉浏览器当检测到跨站脚本攻击时,浏览器将停止加载页面
- 0 表示禁止XSS过滤
- 1 表示启用XSS过滤。如果检测到跨站脚本攻击,浏览器将清除页面。
- 1:mode=block 表示启用XSS过滤。如果检测到攻击,浏览器不会清除页面,而是阻止页面加载。Spring Security设置是这个
1:report=<reporting-URI>
表示启用XSS过滤,如果检测到跨站脚本攻击,浏览器将清除页面并发送违规报告
所谓XSS攻击是Crocs-Site Scripting 跨站脚本攻击,攻击者在网站上注入恶意的JavaScript代码,窃取Cookie信息,监听用户行为,修改DOM结构。
Content-Security-Policy
Content-Security-Policy 为内容安全策略,简称CSP,用于检测并削弱某些特定类型的攻击,例如跨站脚本(XSS)和数据注入攻击
CSF相当于通过一个白名单明确告诉客户端,哪些外部资源可以加载和执行。
Referrer-Policy
Referrer-Policy描述用户从哪里进入到当前页面
Feature-Policy
Feature-Policy提供了一种可以在本页面或包含的iframe上启用或禁止浏览器特性的机制。使用较少
Clear-Site-Data
Clear-Site-Data 一般用在注销登录响应头中,表示告诉浏览器清除当前网站相关的数据,可以通过具体参数指定想要清除的数据,比如cookies cache storage等,也可以通过"*"表示清除所有的数据
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.logout()
.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(ClearSiteDataHeaderWriter.Directive.ALL)))
.and()
.headers().contentTypeOptions().disable()
.csrf().disable()
.headers()
.featurePolicy("vibrate 'none'; geolocation 'none'")
.and()
.referrerPolicy()
.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.ORIGIN_WHEN_CROSS_ORIGIN)
.and()
.contentSecurityPolicy(contentSecurityPolicyConfig -> {
contentSecurityPolicyConfig.policyDirectives("default-src 'self'; script-src 'self'; object-src 'none';style-src cdn.javaboy.org; img-src *; child-src https:;report-uri http://localhost:8081/report");
contentSecurityPolicyConfig.reportOnly();
});
}