经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
springboot2如何禁用自带tomcat的session功能
来源:jb51  时间:2021/11/9 15:50:52  对本文有异议

禁用自带tomcat的session功能

微服务下的各个服务都是无状态的,所以这个时候tomcat的session管理功能是多余的,即时不用,也会消耗性能,关闭后tomcat的性能会有提升,但是springboot提供的tomcat没有配置选项可以直接关闭,研究了一下,tomcat默认的session管理器名字叫:StandardManager,查看tomcat加载源码发现,如果context中没有Manager的时候,直接new StandardManager(),源码片段如下:

  1. Manager contextManager = null;
  2. Manager manager = getManager();
  3. if (manager == null) {
  4. if (log.isDebugEnabled()) {
  5. log.debug(sm.getString("standardContext.cluster.noManager",
  6. Boolean.valueOf((getCluster() != null)),
  7. Boolean.valueOf(distributable)));
  8. }
  9. if ((getCluster() != null) && distributable) {
  10. try {
  11. contextManager = getCluster().createManager(getName());
  12. } catch (Exception ex) {
  13. log.error(sm.getString("standardContext.cluster.managerError"), ex);
  14. ok = false;
  15. }
  16. } else {
  17. contextManager = new StandardManager();
  18. }
  19. }
  20. // Configure default manager if none was specified
  21. if (contextManager != null) {
  22. if (log.isDebugEnabled()) {
  23. log.debug(sm.getString("standardContext.manager",
  24. contextManager.getClass().getName()));
  25. }
  26. setManager(contextManager);
  27. }

为了不让tomcat去new自己的管理器,必须让第二行的getManager()获取到对象,所以就可以从这里入手解决,我的解决办法如下:自定义一个tomcat工厂,继承原来的工厂,context中加入自己写的manager

  1. @Component
  2. public class TomcatServletWebServerFactorySelf extends TomcatServletWebServerFactory {
  3. protected void postProcessContext(Context context) {
  4. context.setManager(new NoSessionManager());
  5. }
  6. }
  1. public class NoSessionManager extends ManagerBase implements Lifecycle {
  2. @Override
  3. protected synchronized void startInternal() throws LifecycleException {
  4. super.startInternal();
  5. try {
  6. load();
  7. } catch (Throwable t) {
  8. ExceptionUtils.handleThrowable(t);
  9. t.printStackTrace();
  10. }
  11. setState(LifecycleState.STARTING);
  12. }
  13. @Override
  14. protected synchronized void stopInternal() throws LifecycleException {
  15. setState(LifecycleState.STOPPING);
  16. try {
  17. unload();
  18. } catch (Throwable t) {
  19. ExceptionUtils.handleThrowable(t);
  20. t.printStackTrace();
  21. }
  22. super.stopInternal();
  23. }
  24. @Override
  25. public void load() throws ClassNotFoundException, IOException {
  26. log.info("HttpSession 已经关闭,若开启请配置:seeyon.tomcat.disableSession=false");
  27. }
  28. @Override
  29. public void unload() throws IOException {}
  30. @Override
  31. public Session createSession(String sessionId) {
  32. return null;
  33. }
  34. @Override
  35. public Session createEmptySession() {
  36. return null;
  37. }
  38. @Override
  39. public void add(Session session) {}
  40. @Override
  41. public Session findSession(String id) throws IOException {
  42. return null;
  43. }
  44. @Override
  45. public Session[] findSessions(){
  46. return null;
  47. }
  48. @Override
  49. public void processExpires() {}
  50. }

两个类解决问题,这样通过request获取session就是空了,tomcat摆脱session这层处理性能有所提升。

禁用内置Tomcat的不安全请求方法

起因:安全组针对接口测试提出的要求,需要关闭不安全的请求方法,例如put、delete等方法,防止服务端资源被恶意篡改。

用过springMvc都知道可以使用@PostMapping、@GetMapping等这种注解限定单个接口方法类型,或者是在@RequestMapping中指定method属性。这种方式比较麻烦,那么有没有比较通用的方法,通过查阅相关资料,答案是肯定的。

tomcat传统形式通过配置web.xml达到禁止不安全的http方法

  1. <security-constraint>
  2. <web-resource-collection>
  3. <url-pattern>/*</url-pattern>
  4. <http-method>PUT</http-method>
  5. <http-method>DELETE</http-method>
  6. <http-method>HEAD</http-method>
  7. <http-method>OPTIONS</http-method>
  8. <http-method>TRACE</http-method>
  9. </web-resource-collection>
  10. <auth-constraint>
  11. </auth-constraint>
  12. </security-constraint>
  13. <login-config>
  14. <auth-method>BASIC</auth-method>
  15. </login-config>

Spring boot使用内置tomcat,2.0版本以前使用如下形式

  1. @Bean
  2. public EmbeddedServletContainerFactory servletContainer() {
  3. TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {// 1
  4. protected void postProcessContext(Context context) {
  5. SecurityConstraint securityConstraint = new SecurityConstraint();
  6. securityConstraint.setUserConstraint("CONFIDENTIAL");
  7. SecurityCollection collection = new SecurityCollection();
  8. collection.addPattern("/*");
  9. collection.addMethod("HEAD");
  10. collection.addMethod("PUT");
  11. collection.addMethod("DELETE");
  12. collection.addMethod("OPTIONS");
  13. collection.addMethod("TRACE");
  14. collection.addMethod("COPY");
  15. collection.addMethod("SEARCH");
  16. collection.addMethod("PROPFIND");
  17. securityConstraint.addCollection(collection);
  18. context.addConstraint(securityConstraint);
  19. }
  20. };

2.0版本使用以下形式

  1. @Bean
  2. public ConfigurableServletWebServerFactory configurableServletWebServerFactory() {
  3. TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
  4. factory.addContextCustomizers(context -> {
  5. SecurityConstraint securityConstraint = new SecurityConstraint();
  6. securityConstraint.setUserConstraint("CONFIDENTIAL");
  7. SecurityCollection collection = new SecurityCollection();
  8. collection.addPattern("/*");
  9. collection.addMethod("HEAD");
  10. collection.addMethod("PUT");
  11. collection.addMethod("DELETE");
  12. collection.addMethod("OPTIONS");
  13. collection.addMethod("TRACE");
  14. collection.addMethod("COPY");
  15. collection.addMethod("SEARCH");
  16. collection.addMethod("PROPFIND");
  17. securityConstraint.addCollection(collection);
  18. context.addConstraint(securityConstraint);
  19. });
  20. return factory;
  21. }

关于内嵌tomcat的更多配置,感兴趣可以阅读官方文档

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号