Login session model combat

Introduction

Login session is a basic operation, no matter which application will use the module, in response to this, I wrote a simple case for the previous spring security function article

Operating procedures

Database Design

Operation link: User Center-Database Design

curd operation tool

Operation link: Springboot implants pagerHelper and spring mybatis to update several operations

Login authentication implementation

Login code

Here is a simple user name and password operation, query user resource path, query user information through user phone number, and match password. The specific code is as follows:

 /**
     * 电话号码登录
     * @param phone 用户电话号码
     * @param password 加密后密码
     * @return
     */
    @Override
    public UserData login(String phone, @NotNull String password) {
    
    
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("userPhone", phone);
        User user = userMapper.selectOneByExample(example);
        if (user != null && password.equals(user.getUserPassword())) {
    
    
            UserData userData = new UserData();
            /**
             * 查询用户资源信息
             */
            userData.setUserResources(resourceMapper.selectResourceByRoleId(user.getId()));
            BeanUtils.copyProperties(user, userData);
            Logon logon = new Logon();
            logon.setToken(UUID.randomUUID().toString().replaceAll("-", ""));
            logon.setUserId(user.getId());
            try {
    
    
                logon.setResourceData(objectMapper.writeValueAsString(userData.getUserResources()));
            } catch (JsonProcessingException e) {
    
    
                e.printStackTrace();
            }
            Example logonExample = new Example(Logon.class);
            logonExample.createCriteria().andEqualTo("userId", user.getId());
            logonMapper.deleteByExample(logonExample);
            logonMapper.insert(logon);
            userData.setToken(logon.getToken());
            return userData;
        }
        return null;
    }

User resource query

Query the sql configuration of user resources

 <select id="selectResourceByRoleId" resultMap="BaseResultMap">
        SELECT `tb_resource`.`id`,
          `resource_code`,
          `resource_url`,
          `resource_description`,
          `resource_state`
         FROM  `tb_resource`
         RIGHT  JOIN  `role_resource`
          ON `tb_resource`.`id` = `role_resource`.`resource_id`
         RIGHT  JOIN `user_role`
           ON `user_role`.`role_id` = `role_resource`.`role_id`
         WHERE `user_role`.`user_id` = #{userId}
    </select>

Login interface

Specific login controller code

package com.lgh.controller;

import com.lgh.common.result.CommonResult;
import com.lgh.common.result.inter.IResult;
import com.lgh.model.domain.UserData;
import com.lgh.service.ILogonService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

@Api(tags = "登录服务")
@RestController
@RequestMapping("/login")
@Validated
public class LogonController {
    
    

    @Autowired
    private ILogonService logonService;

    @ApiOperation("登录服务接口")
    @PostMapping("/sign")
    @Valid
    public IResult<UserData> login(@NotNull @RequestParam("phone") String phone, @NotNull @RequestParam("password") String password) {
    
    
        UserData userData = logonService.login(phone, password);
        return CommonResult.successData(userData);
    }
}

Authentication and authentication

Intercept authentication through spring security filters, and authorization through annotation @RolesAllowed. Because the spring security filter cannot be managed by spring, otherwise it will be intercepted globally, so here you need to get the request interface, get the bean of the service, so get the application class first.

ApplicationUtil tool class

package com.lgh.common.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationUtil implements ApplicationContextAware {
    
    
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    
    
        this.applicationContext = applicationContext;
    }

    public static <T> T getBean(Class<T> t) {
    
    
        return applicationContext.getBean(t);
    }
}

GrantedAuthority permission control class

Since jsr250 will add a prefix, I don’t like the prefix ROLE_, so I also give the prefix by default when I implement GrantedAuthority, as shown in the following code

package com.lgh.common.authority.authentication;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.Assert;

public class MySimpleGrantedAuthority implements GrantedAuthority {
    
    
    private static final long serialVersionUID = 510L;
    private final String rolePrefix = "ROLE_";
    private final String role;

    public MySimpleGrantedAuthority(String role) {
    
    
        Assert.hasText(role, "A granted authority textual representation is required");
        this.role = role;
    }

    public String getAuthority() {
    
    
        return rolePrefix + this.role;
    }

    public boolean equals(Object obj) {
    
    
        if (this == obj) {
    
    
            return true;
        } else {
    
    
            return obj instanceof MySimpleGrantedAuthority ? this.role.equals(((MySimpleGrantedAuthority) obj).role) : false;
        }
    }

    public int hashCode() {
    
    
        return this.role.hashCode();
    }

    public String toString() {
    
    
        return this.role;
    }
}

security Filter authentication

Let's write the actual filter

package com.lgh.common.authority.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lgh.common.authority.authentication.MyAuthentication;
import com.lgh.common.authority.authentication.MySimpleGrantedAuthority;
import com.lgh.common.authority.entity.UserDetail;
import com.lgh.common.result.CommonResult;
import com.lgh.common.util.ApplicationUtil;
import com.lgh.model.Resource;
import com.lgh.model.domain.UserData;
import com.lgh.service.ILogonService;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * spring security过滤器,不要交给spring 管理
 */
public class MyAuthenticationFilter extends OncePerRequestFilter {
    
    


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    
    
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
    
    
            filterChain.doFilter(request, response);
        } else {
    
    
            ILogonService logonService = ApplicationUtil.getBean(ILogonService.class);
            UserData userData = logonService.verify(token);
            if (userData == null) {
    
    
                ObjectMapper objectMapper = ApplicationUtil.getBean(ObjectMapper.class);
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().print(objectMapper.writeValueAsString(CommonResult.deny()));
                return;
            } else {
    
    
                UserDetail userDetail = new UserDetail();
                userDetail.setId(userData.getId());
                userDetail.setName(userData.getUserName());
                List<MySimpleGrantedAuthority> roles = new ArrayList<>();
                if (userData.getUserResources() != null) {
    
    
                    roles = userData.getUserResources().stream()
                            .map(Resource::getResourceCode)
                            .map(MySimpleGrantedAuthority::new)
                            .collect(Collectors.toList());
                }
                MyAuthentication myAuthentication = new MyAuthentication(userDetail, roles);
                SecurityContextHolder.getContext().setAuthentication(myAuthentication);
                filterChain.doFilter(request, response);
            }
        }
    }
}

test

  1. Initialize user information, initialize yourself according to the form
  2. swagger test, as shown below
    Insert picture description here
  3. After logging in, get the corresponding token and request a sample, as shown in the figure
    Insert picture description here

to sum up

  1. You can learn simple user-centric user design from the article
  2. How to use pagerHelper function
  3. Login process design
  4. The use and design of security authentication and common problems (The filter cannot be handed over to spring, set the path to not check web.ignoring(), and the processing of the permission check prefix

Source code

github

Guess you like

Origin blog.csdn.net/soft_z1302/article/details/113085709