在这篇文章中,我想分享一下O&B的一个团队的经验教训。 他们正在使用带有Spring Security的Spring Boot。

默认情况下,Spring Security保护的所有内容都将通过以下HTTP标头发送到浏览器:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate

本质上,响应将永远不会被浏览器缓存。 尽管这似乎效率低下,但实际上有充分的理由要采用这种默认行为。 当一个用户注销时,我们不希望下一个登录的用户能够看到前一个用户的资源(如果缓存了,则可以这样做)。

默认情况下不缓存任何内容,并保留显式启用缓存是有意义的。 但是,如果不缓存任何内容,则不好,因为这会导致高带宽使用和缓慢的页面加载。

很好的是,在Spring Boot中启用静态内容缓存非常容易(即使使用Spring Security也是如此)。 只需配置一个缓存周期。 就是这样!

# Boot 2.x
spring.resources.cache.cachecontrol.max-age=14400# Boot 1.x
spring.resources.cache-period=14400

但是有一些陷阱! 对于某些版本,它不是那么简单! 让我进一步解释。

有几种方法可以返回内容:

  1. 通过Spring Boot自动配置的静态资源请求处理程序的静态内容
  2. 控制器方法返回视图名称(例如,解析为JSP)
  3. 返回HttpEntity (或ResponseEntity )的控制器方法

启用静态内容缓存

第一个(提供静态内容)是通过配置所述属性(通常在如上所述的application.properties中)来处理的。

通过HttpServletResponse设置

在第二种情况下,控制器处理程序方法可以选择通过HttpServletResponse方法参数设置“ Cache-Control”标头。

@Controller
... class ... {@RequestMapping(...)public String ...(..., HttpServletResponse response) {response.setHeader("Cache-Control", "max-age=14400");return ...; // view name}
}

只要Spring Security不会覆盖它,它就可以工作。

通过HttpEntity / ResponseEntity设置

在第三种情况下,控制器处理程序方法可以选择设置返回的HTTP实体的“ Cache-Control”标头。

@Controller
... class ... {@RequestMapping(...)public ResponseEntity<...> ...(...) {return ResponseEntity.ok().cacheControl(...).body(...);}
}

只要Spring Security还没有编写自己的“ Cache-Control”头文件,它就可以工作。

引擎盖下

引擎盖下

要了解其工作时间和原因,以下是相关序列。

对于Spring Security Web 4.0.x,4.2.0和4.2.4及更高版本,将发生以下顺序:

  1. 如果不存在缓存头,则HeaderWriterFilter委托CacheControlHeadersWriter编写“ Cache-Control”头(包括“ Pragma”和“ Expires”)。
  2. 调用控制器处理程序方法(如果匹配)。 该方法可以:
    • HttpServletResponse明确设置标头。
    • 或者,设置在返回的报头HttpEntityResponseEntity (参照handleReturnValue()的方法HttpEntityMethodProcessor )。
      • 请注意,如果HttpEntityMethodProcessor 还不存在HttpEntityMethodProcessor仅将头(来自HttpEntity )写入实际响应。 这是一个问题,因为早在#1中,标头已经设置好了。
  3. 如果没有控制器处理该请求,那么Spring Boot自动配置的静态资源请求处理程序将获得机会。 它尝试提供静态内容,并且如果配置为缓存,它将覆盖“ Cache-Control”标头(并清除“ Pragma”和“ Expires”标头的值,如果有的话)。 静态资源处理程序是ResourceHttpRequestHandler对象(请参阅其WebContentGenerator基类中的applyCacheControl()方法)。
    • 但是,在Spring Web MVC 4.2.5中, WebContentGenerator仅在不存在时才写入“ Cache-Control”标头 。 这是一个问题,因为早在#1中,标头已经设置好了。
    • 在Spring Web MVC 4.2.6及更高版本中,即使它已经存在,它也会添加“ Cache-Control”标头。 因此,即使已在#1中设置了标头也没有问题。

使用Spring Security Web 4.1.x,4.2.5和更高版本(在Spring Boot 1.5.11中使用版本4.2.5),顺序已更改。 它是这样的:

  1. 调用控制器处理程序方法(如果匹配)。 该方法可以:
    • HttpServletResponse明确设置标头。
    • 或者,设置在返回的报头HttpEntityResponseEntity (参照handleReturnValue()的方法HttpEntityMethodProcessor )。
      • 请注意,如果HttpEntityMethodProcessor 还不存在HttpEntityMethodProcessor仅将头(来自HttpEntity )写入实际响应。 没问题,因为尚未设置标题。
  2. 如果没有控制器处理该请求,那么Spring Boot自动配置的静态资源请求处理程序将获得机会。 它尝试提供静态内容,并且如果配置为缓存,它将覆盖“ Cache-Control”标头(并清除“ Pragma”和“ Expires”标头的值,如果有的话)。
  3. 如果不存在缓存头,则HeaderWriterFilter委托CacheControlHeadersWriter编写“ Cache-Control”头(包括“ Pragma”和“ Expires”)。
    • 没问题,因为如果已经设置了缓存头,它将不会覆盖。

工作版本

以上三种控制缓存的情况都在Spring Boot 1.5.11和Spring Boot 2.x中起作用。 但是,如果无法升级到那些版本,请参见以下类,并检查它是否具有您想要的行为(使用上述顺序):

    • HeaderWriterFilter (请参阅doFilterInternal方法)
    • CacheControlHeadersWriter (请参阅writeHeaders()方法)
    • WebContentGenerator (请参阅applyCacheControl()方法)
    • HttpEntityMethodProcessor (请参见handleReturnValue()方法)

另外,请注意,Spring Security Web 4.2.5及更高版本将写入以下HTTP标头(即使已设置它们,也将其覆盖,例如,在控制器中):

    • 通过XContentTypeOptionsHeaderWriter X-Content-Type-Options
    • 通过HstsHeaderWriter Strict-Transport-Security HstsHeaderWriter
    • 通过XFrameOptionsHeaderWriter X-Frame-Options
    • 通过XXssProtectionHeaderWriter X-XSS-Protection

这是因为,与CacheControlHeadersWriter不同,上述内容的标头编写器不会检查标头是否已经存在。 他们只需设置各自的HTTP标头即可。 请参考各自的标题编写器类,并发布#5193 。

另一种选择是让Spring Security忽略静态资源请求。 这样,配置的缓存周期将不会被覆盖。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/css/**", "/js/**");// If the above paths are served by the// Spring Boot auto-configured// static resource request handler,// and a cache period is specified,// then it will have a "Cache-Control"// HTTP header in its response.// And it would NOT get overwritten by Spring Security.}
}

目前为止就这样了。 希望这可以清除一切。

翻译自: https://www.javacodegeeks.com/2018/07/caching-spring-boot-spring-security.html

使用Spring Security在Spring Boot中进行缓存相关推荐

  1. PART 5: INTEGRATING SPRING SECURITY WITH SPRING BOOT WEB

    转自:http://justinrodenbostel.com/2014/05/30/part-5-integrating-spring-security-with-spring-boot-web/ ...

  2. Spring Boot中的缓存支持(一)注解配置与EhCache使用

    随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一.Spring 3开始提供了强大的基于注解的缓 ...

  3. Spring MVC实现Spring Security,Spring Stomp websocket Jetty嵌入式运行

    使用Spring框架各个组件实现一个在线聊天网页,当有用户连接WebSocket,服务器监听到用户连接会使用Stomp推送最新用户列表,有用户断开刷新在线列表,实时推送用户聊天信息.引入Jetty服务 ...

  4. spring security logout(spring security登出示例)

    ** spring security logout(spring security登出示例) ** 在学习实现spring security登出的时候发现了一篇外文,感觉写的挺好,这里斗胆尝试翻译出来 ...

  5. Spring Security with Spring Boot 2.0:使用Servlet堆栈的简单身份验证

    Spring安全性是一个很好的框架,可节省开发人员的大量时间和精力. 此外,它还具有足够的灵活性,可以自定义并满足您的需求. 随着spring的发展,spring安全性也使得在项目中设置安全性变得更加 ...

  6. Spring Security with Spring Boot 2.0:密码编码器

    在上一篇文章中,我们使用了用户详细信息服务,以便提供一种基于给定用户名从函数加载数据的方法. 用户详细信息的实现可能由内存机制,sql / no-sql数据库等支持. 选项是无限的. 关于密码存储,我 ...

  7. Spring Boot中的缓存支持(二)使用Redis做集中式缓存

    上一篇介绍了在Spring Boot中如何引入缓存.缓存注解的使用.以及EhCache的整合. 虽然EhCache已经能够适用很多应用场景,但是由于EhCache是进程内的缓存框架,在集群模式下时,各 ...

  8. Spring Security 在互联网项目中的实战分享

    SpringBoot 和 Spring Cloud 中默认都是使用 Spring Security框架,这门技术非学不可.那么我们在企业中该如何灵活的运用它呢? 本场 Chat 将通过以下几个方面进行 ...

  9. 项目中Spring Security 整合Spring Session实现记住我功能

    Spring Session提供了与Spring Security的"我记得"身份验证的集成的支持: 目的: 更改会话过期长度 确保会话cookie在Integer.MAX_VAL ...

最新文章

  1. 史上最强:numpy实现全部机器学习算法
  2. 用onerror处理图片获取失败问题
  3. linux (ubuntu) 命令学习笔记
  4. python台风动图绘制_使用Python绘制台风轨迹图的示例代码
  5. 缺氧游戏黑科技计算机,《缺氧》游戏内参数修改图文详解
  6. spring—SpringMVC的请求和响应
  7. bzoj 1797: [Ahoi2009]Mincut 最小割 (网络流)
  8. web_submit_data详解
  9. 20165318 2017-2018-2《Java程序设计》课程总结
  10. 菲尼克斯2961105继电器REL-MR- 24DC/21
  11. 伦敦的威斯敏斯特大教堂地下室的墓碑林中,一块震撼全世界的一段碑文。
  12. [R分析] 描述统计:频数和频率分布直方图
  13. Java面试——数据库
  14. 博客园申请js权限方式
  15. 计算机培训ppt教案,课件制作的教案
  16. ②计算机病毒实验实验报告
  17. 设备虚拟化技术之堆叠
  18. Simscape Multibody简介与入门(上) 准备工作
  19. Stream 学习
  20. 解决Ubuntu软件商店无法更新问题

热门文章

  1. 【链表】【树形DP】最大利润(jzoj 1487)
  2. 【动态规划】最大子矩阵之和
  3. 25、sql分析命令explain和desc
  4. Mysql调优你不知道这几点,就太可惜了
  5. 2017年秋招美团Java程序员开发,看我如何拿到offer
  6. 我终于搞清楚了和String有关的那点事儿
  7. Java IO: ByteArray和Filter
  8. springmvc常用注解
  9. 本想试试看,结果却拿到了京东的Offer
  10. 图解分布式架构的演进