1. 程式人生 > >攔截器進行許可權判斷

攔截器進行許可權判斷

定義一個攔截器

/**
 *版權所有:愛wifi無線運營中心
 * 建立日期:2018年10月16日上午11:10:12
 *檔名稱:AccessTokenVerifyInterceptor.java
 *建立作者:付少林
 *
 */
package com.awifi.athena.app.smart.elevator.common.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.awifi.athena.app.smart.elevator.common.business.usermanage.permission.entity.UserPermission;
import com.awifi.athena.app.smart.elevator.common.business.usermanage.user.dto.UserInfoDto;
import com.awifi.athena.app.smart.elevator.common.business.usermanage.user.dto.UserInfoPermissionDto;
import com.awifi.athena.app.smart.elevator.common.constants.Constants;
import com.awifi.athena.app.smart.elevator.common.exception.BizException;
import com.awifi.athena.app.smart.elevator.common.exception.ValidException;
import com.awifi.athena.app.smart.elevator.common.utils.KeyUtil;
import com.awifi.athena.app.smart.elevator.common.utils.MessageUtil;
import com.awifi.athena.app.smart.elevator.common.utils.RequestMappingUrlUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import java.util.List;

/**
 * 驗證token有效性
 */
@Component
public class AccessTokenVerifyInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
        boolean flag = false;
        String accessToken = request.getParameter("access_token");
        if(StringUtils.isNoneBlank(accessToken)) {
        	UserInfoPermissionDto usrDto = KeyUtil.getAdminUserByAccessToken(accessToken);
            if(usrDto!=null){
                List<UserPermission> list = usrDto.getUserPermissions();
                if(list==null||list.size()==0){
                    throw new BizException("E1000003", MessageUtil.getMessage("E1000003"));
                }
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                //拿到請求類的型別
                String beanType = handlerMethod.getBeanType().getName();
                //獲得請求類的位元組碼檔案
                Class clazz = Class.forName(beanType);
                //http請求的url,防止一些url佔位符的問題,對url進行了處理
                String url = RequestMappingUrlUtil.getRequestMappingUrl(clazz,beanType+"."+handlerMethod.getMethod().getName());
                String method = request.getMethod();
                for (UserPermission userPermission:list) {//對url進行處理使url前後都有/方便進行比較,容錯性比較好
                    if(userPermission.getUrl()!=null){
                        if(!userPermission.getUrl().startsWith("/")){
                            userPermission.setUrl("/"+userPermission.getUrl());
                        }
                        if(!userPermission.getUrl().endsWith("/")){
                            userPermission.setUrl(userPermission.getUrl()+"/");
                        }
                    }
                    if(userPermission.getMethod()!=null){
                        userPermission.setMethod(StringUtils.upperCase(userPermission.getMethod()));
                    }
                }
                if(!url.startsWith("/")){
                    url = "/"+url;
                }
                if(!url.endsWith("/")){
                    url = url+"/";
                }
                if(!list.contains(new UserPermission(url,method))){
                    throw new BizException("E1000003", MessageUtil.getMessage("E1000003"));
                }
                flag = true;
                //塞到request中去,供controller裡面呼叫
                request.setAttribute(Constants.SESSION_NAME_USER,usrDto);
            }
        }

        if(!flag){
        	throw new ValidException("E1000002", "請重新登入");
        }
        return flag;
    }

}
package com.awifi.athena.app.smart.elevator.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 版權所有: 愛WiFi無線運營中心
 * 建立日期:2018/12/5
 * 建立作者:付少林
 * 檔名稱:RequestMappingUrlUtil.java
 * 版本:  v1.0
 * 修改記錄:
 */
public class RequestMappingUrlUtil {
    public static String getRequestMappingUrl(Class controller, String methodName) {
        //得到方法
        Method[] methods = controller.getDeclaredMethods();
        String[] value = new String[1];
        Annotation classAnnotation = AnnotationHelper.getInstance().getClassAnnotation(controller, RequestMapping.class);
        String classUrl = "";
        try {
            List<RequestUrlInfo> urlList = getRequestUrlInfos(classAnnotation);
            if(urlList!=null&&urlList.size()>0){
                classUrl = urlList.get(0).getValue();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        for (Method method : methods) {
            String className = controller.getName() + "." + method.getName();
            if (!StringUtils.equals(className, methodName)) {
                continue;
            }
            //得到requestMapping註釋
            RequestMapping annotation = method.getAnnotation(RequestMapping.class);
            GetMapping getAnnotation = method.getAnnotation(GetMapping.class);
            PostMapping postAnnotation = method.getAnnotation(PostMapping.class);
            DeleteMapping deleteAnnotation = method.getAnnotation(DeleteMapping.class);
            PutMapping putAnnotation = method.getAnnotation(PutMapping.class);
            try {
                if (annotation != null) {
                    value[0] = annotation.value()[0];
                }
                if (getAnnotation != null) {
                    value[0] = getAnnotation.value()[0];
                }
                if (postAnnotation != null) {
                    value[0] = postAnnotation.value()[0];
                }
                if (deleteAnnotation != null) {
                    value[0] = deleteAnnotation.value()[0];
                }
                if (putAnnotation != null) {
                    value[0] = putAnnotation.value()[0];
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        }
        return classUrl+value[0];
    }

    /**
     * 將RequestMapping註解資訊,組裝成RequestUrlInfo類中。此類方法共有三種過載方式,分別為Annotation、提供basePath、提供classAnnotation註解三種方式。
     * @param annotation  引數
     * @return  註解資訊
     */
    public  static List<RequestUrlInfo> getRequestUrlInfos(Annotation annotation) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        List<RequestUrlInfo> infos = new ArrayList<>();

        if(annotation == null) {
            return infos;
        }

        String name = (String) AnnotationHelper.getInstance().getAnnotationInfo(annotation, "name");
        List<String> requestUrls = Arrays.asList((String[]) AnnotationHelper.getInstance().getAnnotationInfo(annotation, "value"));
        List<RequestMethod> requestMethods = Arrays.asList((RequestMethod[]) AnnotationHelper.getInstance().getAnnotationInfo(annotation, "method"));

        if(requestMethods.isEmpty()) {
            for(String url : requestUrls) {
                RequestUrlInfo info = new RequestUrlInfo(name);

                info.setValue(url);
                info.setRequestMethod(null);

                infos.add(info);
            }
        } else {
            for(String url : requestUrls) {
                for(RequestMethod method : requestMethods) {
                    RequestUrlInfo info = new RequestUrlInfo(name);

                    info.setValue(url);
                    info.setRequestMethod(method);

                    infos.add(info);
                }
            }
        }

        return infos;
    }
}