攔截器進行許可權判斷
阿新 • • 發佈:2018-12-09
定義一個攔截器
/** *版權所有:愛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; } }