springboot2 How to Disable session Feature with tomcat

  • 2021-12-11 17:54:30
  • OfStack

Directory disable session feature with tomcat disable insecure request method with built-in Tomcat

Disable session feature with tomcat

All services under micro-services are stateless, Therefore, the session management function of tomcat is redundant at this time, and it will consume performance even if it is not used. After closing, the performance of tomcat will be improved, but tomcat provided by springboot can be closed directly without configuration option. After studying 1, the default session manager name of tomcat is StandardManager. Looking at the loading source code of tomcat, if there is no Manager in context, direct new StandardManager (), the source code fragment is as follows:


               Manager contextManager = null;
                Manager manager = getManager();
                if (manager == null) {
                    if (log.isDebugEnabled()) {
                        log.debug(sm.getString("standardContext.cluster.noManager",
                                Boolean.valueOf((getCluster() != null)),
                                Boolean.valueOf(distributable)));
                    }
                    if ((getCluster() != null) && distributable) {
                        try {
                            contextManager = getCluster().createManager(getName());
                        } catch (Exception ex) {
                            log.error(sm.getString("standardContext.cluster.managerError"), ex);
                            ok = false;
                        }
                    } else {
                        contextManager = new StandardManager();
                    }
                }
 
                // Configure default manager if none was specified
                if (contextManager != null) {
                    if (log.isDebugEnabled()) {
                        log.debug(sm.getString("standardContext.manager",
                                contextManager.getClass().getName()));
                    }
                    setManager(contextManager);
                }

In order to prevent tomcat from going to new's own manager, we must let getManager () in line 2 get the object, so we can solve it from here. My solution is as follows: Customize an tomcat factory, inherit the original factory, and add manager written by ourselves in context


@Component
public class TomcatServletWebServerFactorySelf extends TomcatServletWebServerFactory { 
    protected void postProcessContext(Context context) {
        context.setManager(new NoSessionManager());
    }
}

public class NoSessionManager extends ManagerBase implements Lifecycle { 
    @Override
    protected synchronized void startInternal() throws LifecycleException {
        super.startInternal();
        try {
            load();
        } catch (Throwable t) {
            ExceptionUtils.handleThrowable(t);
            t.printStackTrace();
        }
        setState(LifecycleState.STARTING);
    }
 
    @Override
    protected synchronized void stopInternal() throws LifecycleException {
        setState(LifecycleState.STOPPING);
        try {
            unload();
        } catch (Throwable t) {
            ExceptionUtils.handleThrowable(t);
            t.printStackTrace();
        }
        super.stopInternal();
    }
 
    @Override
    public void load() throws ClassNotFoundException, IOException {
        log.info("HttpSession  Has been closed , If turned on, configure: seeyon.tomcat.disableSession=false");
    }
 
    @Override
    public void unload() throws IOException {}
    @Override
    public Session createSession(String sessionId) {
        return null;
    }
 
    @Override
    public Session createEmptySession() {
        return null;
    }
 
    @Override
    public void add(Session session) {}
    @Override
    public Session findSession(String id) throws IOException {
        return null;
    }
    @Override
    public Session[] findSessions(){
        return null;
    }
    @Override
    public void processExpires() {}
}

Two classes solve the problem, so that getting session through request is empty, and the processing performance of tomcat is improved by getting rid of session.

Disable the insecure request method of the built-in Tomcat

Cause: The security group needs to close unsafe request methods, such as put, delete, etc., to prevent server resources from being maliciously tampered with.

Anyone who has used springMvc knows that you can qualify a single interface method type with annotations such as @ PostMapping, @ GetMapping, or specify the method attribute in @ RequestMapping. This way is more troublesome, so there is no more general method, through consulting relevant information, the answer is yes.

The traditional form of tomcat prohibits insecure http methods by configuring web. xml


    <security-constraint>  
       <web-resource-collection>  
          <url-pattern>/*</url-pattern>  
          <http-method>PUT</http-method>  
       <http-method>DELETE</http-method>  
       <http-method>HEAD</http-method>  
       <http-method>OPTIONS</http-method>  
       <http-method>TRACE</http-method>  
       </web-resource-collection>  
       <auth-constraint>  
       </auth-constraint>  
    </security-constraint>  
    <login-config>  
      <auth-method>BASIC</auth-method>  
    </login-config>

Spring boot uses the built-in tomcat, previously used in version 2.0 as follows


@Bean  
public EmbeddedServletContainerFactory servletContainer() {  
    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {// 1  
        protected void postProcessContext(Context context) {  
            SecurityConstraint securityConstraint = new SecurityConstraint();  
            securityConstraint.setUserConstraint("CONFIDENTIAL");  
            SecurityCollection collection = new SecurityCollection();  
            collection.addPattern("/*");  
            collection.addMethod("HEAD");  
            collection.addMethod("PUT");  
            collection.addMethod("DELETE");  
            collection.addMethod("OPTIONS");  
            collection.addMethod("TRACE");  
            collection.addMethod("COPY");  
            collection.addMethod("SEARCH");  
            collection.addMethod("PROPFIND");  
            securityConstraint.addCollection(collection);  
            context.addConstraint(securityConstraint);  
        }  
    };

Version 2.0 uses the following form


@Bean
public ConfigurableServletWebServerFactory configurableServletWebServerFactory() {
    TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
    factory.addContextCustomizers(context -> {
        SecurityConstraint securityConstraint = new SecurityConstraint();
        securityConstraint.setUserConstraint("CONFIDENTIAL");
        SecurityCollection collection = new SecurityCollection();
        collection.addPattern("/*");
        collection.addMethod("HEAD");
        collection.addMethod("PUT");
        collection.addMethod("DELETE");
        collection.addMethod("OPTIONS");
        collection.addMethod("TRACE");
        collection.addMethod("COPY");
        collection.addMethod("SEARCH");
        collection.addMethod("PROPFIND");
        securityConstraint.addCollection(collection);
        context.addConstraint(securityConstraint);
    });
    return factory;
}

For more configuration of embedded tomcat, please read the official documents.


Related articles: