亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Spring AOP實現功能權限校驗功能的示例代碼

2024-07-13 10:14:16
字體:
來源:轉載
供稿:網友

實現功能權限校驗的功能有多種方法,其一使用攔截器攔截請求,其二是使用AOP拋異常。

首先用攔截器實現未登錄時跳轉到登錄界面的功能。注意這里沒有使用AOP切入,而是用攔截器攔截,因為AOP一般切入的是service層方法,而攔截器是攔截控制器層的請求,它本身也是一個處理器,可以直接中斷請求的傳遞并返回視圖,而AOP則不可以。

1.使用攔截器實現未登錄時跳轉到登錄界面的功能

1.1 攔截器SecurityInterceptor

package com.jykj.demo.filter;import java.io.PrintWriter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import com.alibaba.fastjson.JSON;import com.jykj.demo.util.Helper;import com.jykj.demo.util.Result;public class SecurityInterceptor implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)   throws Exception {  System.out.println("SecurityInterceptor:"+request.getContextPath()+","+request.getRequestURI()+","+request.getMethod());  HttpSession session = request.getSession();  if (session.getAttribute(Helper.SESSION_USER) == null) {   System.out.println("AuthorizationException:未登錄!"+request.getMethod());   if("POST".equalsIgnoreCase(request.getMethod())){    response.setContentType("text/html; charset=utf-8");     PrintWriter out = response.getWriter();     out.write(JSON.toJSONString(new Result(false,"未登錄!")));    out.flush();    out.close();   }else{    response.sendRedirect(request.getContextPath()+"/login");    }   return false;  } else {   return true;  } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,   ModelAndView modelAndView) throws Exception {  // TODO Auto-generated method stub } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)   throws Exception {  // TODO Auto-generated method stub }}

1.2.spring-mvc.xml(攔截器配置部分)

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <mvc:resources mapping="/resources/**" location="/resources/" /><mvc:interceptors>  <mvc:interceptor>   <mvc:mapping path="/*"/> <!-- 攔截/ /test /login 等等單層結構的請求 -->    <mvc:mapping path="/**/*.aspx"/><!-- 攔截后綴為.aspx的請求 -->   <mvc:mapping path="/**/*.do"/><!-- 攔截后綴為 .do的請求 -->   <mvc:exclude-mapping path="/login"/>   <mvc:exclude-mapping path="/signIn"/>   <mvc:exclude-mapping path="/register"/>   <bean class="com.jykj.demo.filter.SecurityInterceptor">   </bean>  </mvc:interceptor> </mvc:interceptors>

這里需要特別說明:攔截器攔截的路徑最好是帶有后綴名的,否則一些靜態的資源文件不好控制,也就是說請求最好有一個統一的格式如 .do 等等,這樣匹配與過濾速度會非??臁H绻贿@樣,例如 用 /** 來攔截所有的請求,則頁面渲染速度會非常慢,因為資源文件也被攔截了。

2.使用AOP實現功能權限校驗

對于功能權限校驗也可以類似地用攔截器來實現,只不過會攔截所有的請求,對不需要權限校驗的請求沒有很好的過濾功能,所以采用AOP指定攔截需要校驗的方法的方式來實現之。

2.1 切面類 PermissionAspect

package com.jykj.demo.filter;import java.io.IOException;import java.lang.reflect.Method;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import com.jykj.demo.annotation.ValidatePermission;import com.jykj.demo.exception.AccessDeniedException;import com.jykj.demo.service.SysUserRolePermService;/** * 事件日志 切面,凡是帶有 @ValidatePermission 以及@ResponseBody注解 控制器 都要進行 功能權限檢查, * 若無權限,則拋出AccessDeniedException 異常,該異常將請求轉發至一個控制器,然后將異常結果返回 * @author Administrator * */public class PermissionAspect { @Autowired SysUserRolePermService sysUserRolePermService; public void doBefore(JoinPoint jp) throws IOException{  System.out.println(    "log PermissionAspect Before method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName());  Method soruceMethod = getSourceMethod(jp);  if(soruceMethod!=null){   ValidatePermission oper = soruceMethod.getAnnotation(ValidatePermission.class);   if (oper != null) {    int fIdx = oper.idx();    Object[] args = jp.getArgs();    if (fIdx>= 0 &&fIdx<args.length){     int functionId = (Integer) args[fIdx];     String rs = sysUserRolePermService.permissionValidate(functionId);     System.out.println("permissionValidate:"+rs);     if(rs.trim().isEmpty()){      return ;//正常     }    }   }  }  throw new AccessDeniedException("您無權操作!"); } private Method getSourceMethod(JoinPoint jp){  Method proxyMethod = ((MethodSignature) jp.getSignature()).getMethod();  try {   return jp.getTarget().getClass().getMethod(proxyMethod.getName(), proxyMethod.getParameterTypes());  } catch (NoSuchMethodException e) {   e.printStackTrace();  } catch (SecurityException e) {   e.printStackTrace();  }  return null; }}

2.2自定義注解ValidatePermission

package com.jykj.demo.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * @Descrption該注解是標簽型注解,被此注解標注的方法需要進行權限校驗 */@Target(value = ElementType.METHOD)@Retention(value = RetentionPolicy.RUNTIME)@Documentedpublic @interface ValidatePermission { /**  * @Description功能Id的參數索引位置 默認為0,表示功能id在第一個參數的位置上,-1則表示未提供,無法進行校驗  */ int idx() default 0;}

說明: AOP切入的是方法,不是某個控制器請求,所以不能直接返回視圖來中斷該方法的請求,但可以通過拋異常的方式達到中斷方法執行的目的,所以在before通知中,如果通過驗證直接return返回繼續執行連接點方法,否則拋出一個自定義異常AccessDeniedException來中斷連接點方法的執行。該異常的捕獲可以通過系統的異常處理器(可以看做控制器)來捕獲并跳轉到一個視圖或者一個請求。這樣就達到攔截請求的目的。所以需要配置異常處理器。

2.3 spring-mvc.xml(異常處理器配置,以及aop配置)

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  <!-- <property name="defaultErrorView" value="rediret:/error"></property> -->  <property name="exceptionMappings">   <props>    <!--<prop key="com.jykj.demo.exception.AuthorizationException">redirect:/login</prop>-->    <prop key="com.jykj.demo.exception.AccessDeniedException">forward:/accessDenied</prop>   </props>  </property> </bean><bean id="aspectPermission" class="com.jykj.demo.filter.PermissionAspect" /> <!-- 對帶有@ValidatePermission和ResponseBody注解的controller包及其子包所有方法執行功能權限校驗 -->  <aop:config proxy-target-class="true">   <aop:aspect ref="aspectPermission">    <aop:pointcut id="pc"     expression="@annotation(com.jykj.demo.annotation.ValidatePermission)     and @annotation(org.springframework.web.bind.annotation.ResponseBody)     and execution(* com.jykj.demo.controller..*.*(..)) " />    <aop:before pointcut-ref="pc" method="doBefore"/>   </aop:aspect>  </aop:config>

2.4 注解需要進行功能校驗的控制器請求

@RequestMapping(value = "/moduleAccess.do", method = RequestMethod.POST, produces="text/html;charset=utf-8") @ResponseBody @ValidatePermission public String moduleAccess(int fid,String action,FrmModule module) {  System.out.println("fid:"+fid+",action:"+action);  int rs = -1;  try{   if(Helper.F_ACTION_CREATE.equals(action)){    rs = moduleService.access(module,Helper.DB_ACTION_INSERT);    //module.setModuleid(rs);    module = moduleService.selectByPrimaryKey(rs);   }else if(Helper.F_ACTION_EDIT.equals(action)){    rs = moduleService.access(module,Helper.DB_ACTION_UPDATE);    module = moduleService.selectByPrimaryKey(module.getModuleid());   }else if(Helper.F_ACTION_REMOVE.equals(action)){    rs = moduleService.access(module,Helper.DB_ACTION_DELETE);   }else{    return JSON.toJSONString(new Result(false,"請求參數錯誤:action"));   }  }catch(Exception e){   e.printStackTrace();   return JSON.toJSONString(new Result(false,"操作失敗,出現異常,請聯系管理員!"));  }  if(rs<0){   return JSON.toJSONString(new Result(false,"操作失敗,請聯系管理員!"));  }  return JSON.toJSONString(new Result(true,module)); }

2.5 異常處理器將請求轉發到的控制器請求 forward:/accessDenied

@RequestMapping(value = "/accessDenied",produces = "text/html;charset=UTF-8")@ResponseBodypublic String accessDenied(){ return JSON.toJSONString(new Result(false,"您沒有權限對此進行操作!"));}

2.6 請求校驗不通過時 由上述的控制器返回 結果本身

如下所示:

{"info":"您沒有權限對此進行操作!","success":false}

2.7 功能校驗service 示例

/**  * 校驗當前用戶在某個模塊的某個功能的權限  * @param functionId  * @return 空字符串表示 有權限 ,否則是錯誤信息  * @throws Exception   */ public String permissionValidate(int functionId){  Object o = request.getSession().getAttribute(Helper.SESSION_USER);  //if(o==null) throw new AuthorizationException();   SysUser loginUser= (SysUser)o;  if(loginUser.getUserid() == 1) return "";  try{   return mapper.permissionValidate(loginUser.getUserid(),functionId);  }catch(Exception ex){   ex.printStackTrace();   return "數據庫操作出現異常!";  } }

說明: 這里僅僅是對帶有@ValidatePermission和@ResponseBody注解的controller包及其子包所有方法進行切入,這樣肯定是不夠通用的,應該是對帶有@ValidatePermission的方法進行切入,在切面類中通過判斷該方法是否有@ResponseBody注解來拋出不一樣的異常,若帶有@ResponseBody注解則拋出上述的異常返回json字符串,
否則,應該拋出另一個自定義異常然后將請求重定向到一個合法的視圖如error.jsp .

通過客戶端發送 /moduleAccess.do 請求,該請求對應的方法同時具有@ValidatePermission和@ResponseBody,并且有功能Id參數fid,這樣AOP可以切入該方法,執行doBefore通知,通過功能參數fid,對它結合用戶id進行權限校驗,若校驗通過直接返回,程序繼續執行,否則拋出自定義異常AccessDeniedException,該異常由系統捕獲(需要配置異常處理器)并發出請求 forward:/accessDenied ,然后對應的控制器 /accessDenied 處理該請求返回一個包含校驗失敗信息的json給客戶端。這樣發送 /moduleAccess.do 請求,如果校驗失敗,轉發到了/accessDenied請求,否則正常執行。繞了這么一個大圈子才實現它。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美午夜精品久久久久久浪潮| 亚洲欧美日韩中文在线| 国产精品精品一区二区三区午夜版| 色悠悠国产精品| 欧美疯狂做受xxxx高潮| 国产日韩av高清| 亚洲女人天堂视频| 国产日产欧美a一级在线| 日韩欧美在线一区| 国产午夜精品麻豆| 久久99久久久久久久噜噜| 亚洲最大激情中文字幕| 日韩av最新在线| 日韩三级影视基地| 国产精品一区二区三区久久| 亚洲区免费影片| 欧美国产精品va在线观看| 最近2019年手机中文字幕| 国产日韩在线精品av| 精品国产一区二区三区在线观看| 国产日韩欧美日韩大片| 在线播放精品一区二区三区| 岛国av在线不卡| 成人免费自拍视频| 亚洲一区二区三区视频播放| 成人黄在线观看| 亚洲美女性生活视频| 热久久99这里有精品| 亚洲免费av电影| 亚洲一区二区三区四区视频| 久久久视频免费观看| 亚洲白拍色综合图区| 精品自在线视频| 美女av一区二区三区| 欧美人成在线视频| 91精品国产成人www| 国产大片精品免费永久看nba| 日韩激情视频在线| 18性欧美xxxⅹ性满足| 亚洲一级免费视频| 午夜欧美大片免费观看| 久久久免费精品视频| 成人伊人精品色xxxx视频| 91国内揄拍国内精品对白| 日韩激情片免费| 欧美专区中文字幕| 国产精品久久久久久久天堂| 91av在线免费观看| 国产精品欧美日韩| 日韩美女中文字幕| 欧美极度另类性三渗透| 热久久免费视频精品| 久久这里只有精品99| 人人澡人人澡人人看欧美| 国产精品三级美女白浆呻吟| 欧美电影免费在线观看| 日本一区二区在线播放| 国产精品久久激情| 91精品中文在线| 久久69精品久久久久久国产越南| 精品久久久国产| 久久精品99久久久久久久久| 欧美成人中文字幕在线| 精品视频一区在线视频| 久久久久国产精品www| 亚洲日韩欧美视频一区| 91视频免费网站| www.亚洲男人天堂| 成人日韩av在线| 欧美国产欧美亚洲国产日韩mv天天看完整| 黑人与娇小精品av专区| 97在线视频免费看| 亚洲国产精品人久久电影| 欧美色另类天堂2015| 免费97视频在线精品国自产拍| 亚洲网址你懂得| 国产精品wwww| 午夜精品久久久久久久99黑人| 国产精品爽黄69| 操91在线视频| 欧美极品美女电影一区| 欧美黑人国产人伦爽爽爽| 原创国产精品91| 久久国产精品影片| 日韩a**中文字幕| 亚洲另类欧美自拍| 欧美一级高清免费| 亚洲国产精品国自产拍av秋霞| 亚洲国产高潮在线观看| 久久精品国产欧美亚洲人人爽| 国产精品成人久久久久| 亚洲欧美日韩图片| 欧美在线视频免费播放| 久久免费视频网站| 亚洲黄页网在线观看| 欧美精品亚州精品| 欧美国产在线视频| 久久精品久久久久久国产 免费| 在线成人一区二区| 欧美做受高潮1| 最近2019年日本中文免费字幕| 亚洲第一级黄色片| 欧美性资源免费| 国语对白做受69| 夜夜狂射影院欧美极品| 7m第一福利500精品视频| 91在线观看免费高清完整版在线观看| 亚洲图片欧洲图片av| 久久精品国产v日韩v亚洲| 亚洲午夜国产成人av电影男同| 欧美中文字幕在线视频| 蜜月aⅴ免费一区二区三区| 欧美一区二区三区免费观看| 国产精品免费久久久久久| 欧美日韩性视频在线| 国产成人精品999| 久久福利视频网| 亚洲综合色激情五月| 日韩精品电影网| 黄色精品在线看| 亚洲国产成人爱av在线播放| 国产精品一区二区久久久| 亚洲xxx自由成熟| 国产成人一区二| 久久久免费在线观看| 国产激情综合五月久久| 热99在线视频| 在线午夜精品自拍| 久久久久久久久久久国产| 亚洲精品乱码久久久久久金桔影视| 国产精品久久久久久久久影视| 国产999视频| 亚洲天堂av在线免费观看| 国产一区二区三区在线观看视频| 91精品久久久久久久久青青| 中文字幕日韩在线视频| 欧美与黑人午夜性猛交久久久| 久久99久久久久久久噜噜| 日韩欧美成人网| 亚洲精品aⅴ中文字幕乱码| 国产精品久久久久高潮| 国产精品jvid在线观看蜜臀| 久久久久国产精品www| 国产精品久久中文| 另类色图亚洲色图| 综合网日日天干夜夜久久| 久久综合亚洲社区| 久久国产精品久久久久久久久久| 久久伊人精品视频| 91超碰中文字幕久久精品| 亚洲综合视频1区| 精品久久久久久| 久久免费国产精品1| 国产亚洲福利一区| 亚洲一区二区黄| 国产精品久久久av久久久| 亚洲欧美一区二区三区在线| 亚洲人成伊人成综合网久久久| 一本一本久久a久久精品牛牛影视| 国产一区二区黑人欧美xxxx| 欧美肥老太性生活视频| 久久精品国产亚洲精品2020| 国内精品美女av在线播放| 国产色视频一区|