Spring Security combat (four) - session management

Table of contents

1. Understanding the conversation

2. Defense against session fixation attacks

 3. Session expires

4. Session concurrency control

5. Defects of cluster sessions

6. Solutions for cluster sessions

7. Integrate Spring Session to solve cluster session problems


         Just log in with the same account in two browsers and you will find that the system does not have any concurrent session restrictions. It is not a good strategy for an account to be logged in from multiple places at the same time. Spring Security has provided us with comprehensive session management functions, including session fixation attacks, session timeout detection, and session concurrency control.

1. Understanding the conversation

        Session (session) is a solution for stateless HTTP to maintain user state. The statelessness of HTTP itself makes there is no correlation between each request during the user's interaction with the server. This means that the user's visit has no identity record, and the site cannot provide users with personalized services. The birth of session solves this problem.

        The server makes an association between different requests by agreeing with the user that each request carries information of an id class. When a user accesses the system for the first time, the system will generate a sessionId for the user and add it to the cookie . During the user's session, each request automatically carries the cookie, so the system can easily identify which user the request came from.

Session fixation attack:

        Hackers only need to visit the system once, extract and piece together the sessionId generated by the system on the URL, and then send the URL to some trusted users. As long as the user logs in through this URL within the validity period of the session, the sessionId will be bound to the user's identity, and hackers can easily enjoy the same session state without the need for a user name and password. This is a session fixation attack.

2. Defense against session fixation attacks

         The way to defend against session fixation attacks is very simple, just regenerate a new session before the user logs in, and Spring Security has enabled this configuration when inheriting WebSecurityConfigureAdapter.

        sessionManagement is a session management configurator. There are four strategies for defending against session fixation attacks:

  • none: do not make any changes, use the old session after login
  • newSession: Create a new session after logging in
  • migrateSession: Create a new session after logging in, and copy the data in the old session
  • changeSessionId: Do not create a new session, but use the session fixation protection provided by the Servlet container

The migrateSession strategy is enabled by default, and can be modified as needed, such as:

 

 3. Session expires

        In addition to defending against session fixation attacks, you can also configure some session expiration policies through Spring Security, such as jumping to a certain URL when it expires:

 It is also possible to completely customize the expiration policy:

public class MyInvalidSessionStrategy implements InvalidSessionStrategy {
    @Override
    public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write("session无效,已过期!");
    }
}

4. Session concurrency control

        Set the maximum number of sessions that a single user is allowed to be online at the same time. If there is no additional configuration, the new login session will kick the old session.

 View the effect:

 

After another browser logs in, the previous browser will prompt this message. When changed to maximumSession(2), two browsers can log in at the same time.

5. Defects of cluster sessions

        Most cluster deployments will adopt a network structure similar to the following figure:

        Under this network structure, user requests will first go to the LB (load balancing) server, and the LB server will forward these requests to the following services according to the load balancing strategy to achieve the purpose of request dispersion. Under normal circumstances, in the cluster, the same user's request may be distributed to different servers , and the login operation is completed on Server1. Server1 caches the user's login status, but Server2 and Server0 do not know it. If the user Subsequent operations are assigned to Server2 or Server0, and the user will be required to log in again. This is a typical session state cluster out of sync problem.

6. Solutions for cluster sessions

        There are three common scenarios for cluster sessions:

  • Session retention - forward the same client's request to the same server
  • Session replication - session data synchronization between cluster servers
  • Session sharing - store the session on an independent server and share it. In the intranet environment, a highly available Redis server is the best choice. Redis's memory-based features allow it to have extremely high read and write performance. High-availability deployment not only reduces network I/O loss, but also improves stability.

7. Integrate Spring Session to solve cluster session problems

(1) Add dependencies

        <!--spring session核心依赖-->
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
            <version>2.4.2</version>
        </dependency>

        <!--springboot 整合redis核心依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!-- 使用Jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.6.0</version>
        </dependency>

 (2) Configure Spring Session

Cluster-backed session registry for Spring Security

@Configuration
@EnableRedisHttpSession
public class HttpSessionConfig {
  
    // 提供redis连接,localhost:6379
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new JedisConnectionFactory();
    }
  
    @Bean
    public SpringSessionBackedSessionRegistry springSessionBackedSessionRegistry(
            FindByIndexNameSessionRepository sessionRepository) {
        return new SpringSessionBackedSessionRegistry(sessionRepository);
    }
  
    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }
}

    

In this class, the @Autowired annotation is used to inject the RedisConnectionFactory object. The RedisConnectionFactory object is used to create a RedisTemplate object for operating Redis to store session data.

The @Bean annotation is used to define three beans:

  1. The sessionRedisOperations method returns a RedisTemplate object for operating Redis to store session data.

  2. The sessionRepository method returns a FindByIndexNameSessionRepository object, which is an implementation class provided by Spring Session for managing HttpSession.

  3. The sessionRepository method also returns a MapSessionRepository object, which is used to store the Session in memory without a Redis environment.

In this class, two implementations of redis storage session and memory storage session are configured, and the corresponding implementation can be selected according to needs.

It should be noted that if you want to use Redis to store sessions, you must ensure that the Redis environment has been correctly configured, including information such as the address and port of the Redis server.

(3) Provide the new session registry to Spring Security

 (4) Start the service test on a different port

The default service is started on port 8080, here we start another one on port 8081:

 After both ports are enabled, first access port 8080, and then access port 8081:

 At this time, refresh the page of port 8080, and you can see that it has been squeezed out by users on port 8081:

 You can also see the stored session information in redis:

 

Guess you like

Origin blog.csdn.net/weixin_49561506/article/details/130180403