Spring boot + redis for single sign on

1. Why is single sign on

web application has developed from single system to multi system. Facing so many systems, it is not realistic for users to log in one by one. Single sign on is to solve this problem.

The complexity of web applications should be borne by the system, not the users. No matter how complex the web system is, it is a unified whole for users, that is to say, the whole application group of users accessing the web system is the same as accessing a single system, one login is enough.

2. Implementation of single sign on

1.session sharing is not commonly used to implement single sign on, because session is used, and the underlying layer of session is cookie. Therefore, if this method is used, the client must support cookie

2. With token, you can use the original OAuth2 protocol or customize the authentication process

Specific process

(1) Client sends user name / password to server
(2) The server obtains the user name and password and then performs the authentication operation
(2.1) if the authentication is successful, a token will be generated, with the token as the key and the JSON string of user information as value. The data will be stored on redis. At the same time, the expiration time of the data will be set, and then the token will be returned to the client.
(2.2) if the authentication fails, you can directly return the failed information.
(3) After the client gets the token returned by the server, it saves it. Later, when the client initiates any request, it needs to take this parameter. When the server processes the client's request, it extracts the token and queries the data in redis. If it can find it, it can get all the information of the user, including the user's role, authority, etc. If not, it indicates that the user is not logged in or the login has expired, and prompts the user to log in again.
(4) The server also needs to provide an additional interface to refresh the token. Users can exchange the old token for a new one.

3. Code implementation

1. Create a spring boot project and integrate Redis. Refer to the specific implementation of spring boot to integrate Redis Spring boot integrates Redis.

pom.xml adds the following dependencies

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2 configure the connection Redis information in the resources/application.properties configuration file

spring.redis.database=0
spring.redis.host=192.168.2.10
spring.redis.port=6379
spring.redis.password=123456
spring.redis.lettuce.pool.min-idle=5
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=1ms
spring.redis.lettuce.shutdown-timeout=100ms

3. Create LoginController front controller

@RestController
public class LoginController {
    @Autowired
    RedisTemplate redisTemplate;

    /**
     * Login interface
     * @param user User object
     * @return s The key of the voucher stored in Redis
     * @throws JsonProcessingException
     */
    @PostMapping(value = "/doLogin",produces = "text/html;charset=utf-8")
    public String login(User user) throws JsonProcessingException {
        ValueOperations ops = redisTemplate.opsForValue();
        if ("zhangsan".equals(user.getUsername()) && "123456".equals(user.getPassword())){
            String s = UUID.randomUUID().toString();
            ObjectMapper om = new ObjectMapper();
            ops.set(s,om.writeValueAsString(user));//Deposit voucher in Redis
            redisTemplate.expire(s,30,TimeUnit.MINUTES);//Set expiration time, 30 minutes
            return s;
        }
        return "Login failed!";
    }
    /**
     * Test interface
     * @param token
     * @return
     */
    @GetMapping("/hello")
    public String hello(String token){
        return "hello";
    }
}

4. Create a LoginInterceptor interceptor to intercept the front-end requests and determine whether it is legal.

@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    RedisTemplate redisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getParameter("token");
        ValueOperations ops = redisTemplate.opsForValue();
        String user = (String) ops.get(token);
        if (user==null || "".equals(user)){
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            out.write("Illegal request");
            return false;
        }
        return true;
    }
}

5. Create WebMVCConfig configuration class and define interceptor interception rules

@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
    @Autowired
    LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")//Path to intercept
                .excludePathPatterns("/doLogin");//Exclude / doLogin path
    }
}

4. Test

1. Visit http://localhost:8080/doLogin

2. Visit http://localhost:8080/hello?token=40a629cf-6d6e-4c02-bb59-2114a807d355. Value returned by token accessing doLogin

3. Visit http://localhost:8080/hello?token=40a629cf-6d6e-4c02-bb59-2114a807d355. If the token expires or does not log in, it indicates that the request is illegal

Tags: Programming Redis Spring Session JSON

Posted on Wed, 06 May 2020 03:36:00 -0400 by ttomnmo