All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.shitsurei.service.handler.RbacAuthorityServiceImpl Maven / Gradle / Ivy

The newest version!
package io.github.shitsurei.service.handler;

import io.github.shitsurei.dao.constants.CustomProperties;
import io.github.shitsurei.dao.enumerate.system.DataStatus;
import io.github.shitsurei.dao.pojo.bo.system.LoginUser;
import io.github.shitsurei.dao.pojo.po.system.SystemMenu;
import io.github.shitsurei.service.system.ISystemMenuBusiness;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 自定义权限校验
 *
 * @author zhanggr-b
 * @version 1.0
 * @date 2021/12/30 17:44
 */
@Component
@Slf4j
public class RbacAuthorityServiceImpl {

    @Autowired
    private RequestMappingHandlerMapping handlerMapping;

    @Autowired
    private ISystemMenuBusiness menuBusiness;

    @Autowired
    private CustomProperties properties;

    /**
     * 记录当前纳入权限验证的接口
     */
    private Map authUrlMap;

    /**
     * 记录系统中所有URL请求
     */
    private Map allUrlMap;

    /**
     * 判断用户访问权限
     *
     * @param request
     * @param authentication
     * @return
     */
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        if (!checkRequest(request)) {
            return true;
        }
        // 去掉统一前缀路由
        SystemMenu menu = menuBusiness.findSystemMenuByUrlAndHttpMethod(request.getRequestURI().replace(properties.getContextPath(), ""), HttpMethod.resolve(request.getMethod()));
        /**
         * 情况1:查询不到,说明接口未通过注解加入权限校验
         * 情况2:数据状态为INVALID说明接口不进行权限校验
         */
        if (Objects.isNull(menu) || menu.getDataStatus() == DataStatus.INVALID) {
            return true;
        }
        Object userInfo = authentication.getPrincipal();
        if (!(userInfo instanceof UserDetails)) {
            return false;
        }
        boolean hasPermission = false;
        LoginUser principal = (LoginUser) userInfo;
        List systemMenuList = menuBusiness.queryByMenuCode(principal.getMenuList());
        for (SystemMenu systemMenu : systemMenuList) {
            AntPathRequestMatcher antPathMatcher = new AntPathRequestMatcher(systemMenu.getUrlPath(), systemMenu.getHttpMethod().name());
            if (antPathMatcher.matches(request)) {
                hasPermission = true;
                break;
            }
        }
        return hasPermission;
    }

    /**
     * 校验请求是否存在,并且返回接口是否纳入权限管控(未纳入权限管控的请求直接放行)
     *
     * @param request 请求
     * @return true表示纳入权限管控
     */
    private boolean checkRequest(HttpServletRequest request) {
        // 去掉统一前缀路由
        String key = request.getRequestURI().replace(properties.getContextPath(), "") + "_" + request.getMethod();
        if (!getAllUrlMap().containsKey(key)) {
            return false;
        }
        if (getAuthUrlMap().containsKey(key)) {
            return true;
        }
        return false;
    }

    /**
     * 获取 所有URL Mapping,返回格式为{"/test":["GET","POST"],"/sys":["GET","DELETE"]}
     *
     * @return {@link ArrayListMultimap} 格式的 URL Mapping
     */
    private Map getAllUrlMap() {
        if (Objects.nonNull(allUrlMap)) {
            return allUrlMap;
        }
        synchronized (RbacAuthorityServiceImpl.class) {
            allUrlMap = Maps.newHashMap();
            // 获取url与类和方法的对应信息
            Map handlerMethods = handlerMapping.getHandlerMethods();
            handlerMethods.forEach((mappingInfo, handlerMethod) -> {
                // 获取当前 key 下的获取所有URL
                Set urls = mappingInfo.getPatternsCondition().getPatterns();
                Set methods = mappingInfo.getMethodsCondition().getMethods();
                urls.forEach(url -> methods.forEach(method -> allUrlMap.put(url + "_" + method, Boolean.TRUE)));
            });
        }
        return allUrlMap;
    }

    /**
     * 获取纳入权限管控的URL集合
     *
     * @return
     */
    private Map getAuthUrlMap() {
        if (Objects.nonNull(authUrlMap)) {
            return authUrlMap;
        }
        synchronized (RbacAuthorityServiceImpl.class) {
            authUrlMap = Maps.newHashMap();
            menuBusiness.findAll().forEach(menu -> authUrlMap.put(menu.getUrlPath() + "_" + menu.getHttpMethod().name(), Boolean.TRUE));
        }
        return authUrlMap;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy