AOP 在實(shí)際項(xiàng)目中運(yùn)用的場(chǎng)景主要有 權(quán)限管理(Authority Management)、事務(wù)管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和調(diào)試管理(Debugging) 等。
創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供汕頭網(wǎng)站建設(shè)、汕頭做網(wǎng)站、汕頭網(wǎng)站設(shè)計(jì)、汕頭網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、汕頭企業(yè)網(wǎng)站模板建站服務(wù),十多年汕頭做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
問(wèn)題源于項(xiàng)目開(kāi)發(fā)
最近項(xiàng)目中需要做一個(gè)權(quán)限管理模塊,按照之前同事的做法是在controller層的每個(gè)接口調(diào)用之前上做邏輯判斷,這樣做也沒(méi)有不妥,但是代碼重復(fù)率太高,而且是體力勞動(dòng),so,便有了如題所說(shuō)的使用spring aop做一個(gè)切點(diǎn)來(lái)實(shí)現(xiàn)通用功能的權(quán)限管理,這樣也就降低了項(xiàng)目后期開(kāi)發(fā)的可擴(kuò)展性。
權(quán)限管理的代碼實(shí)現(xiàn)與配置文件
在最小的代碼修改程度上,aop無(wú)疑是最理想的選擇。項(xiàng)目中有各種權(quán)限的復(fù)合,相對(duì)來(lái)說(shuō)邏輯復(fù)雜度比較高,所以一步步來(lái)。因?yàn)闄?quán)限涉及到的是后端接口的調(diào)用所以樓主選擇在controller層代碼做切面,而切點(diǎn)就是controller中的各個(gè)方法塊,對(duì)于通用訪問(wèn)權(quán)限,我們使用execution表達(dá)式進(jìn)行排除。
只讀管理員權(quán)限的實(shí)現(xiàn)及切點(diǎn)選擇
對(duì)于實(shí)現(xiàn)排除通用的controller,樓主采用的是execution表達(dá)式邏輯運(yùn)算。因?yàn)橹蛔x管理員擁有全局讀權(quán)限,而對(duì)于增刪改權(quán)限,樓主采用的是使用切點(diǎn)切入是增刪改的方法,so,這個(gè)時(shí)候規(guī)范的方法命名就很重要了。對(duì)于各種與只讀管理員進(jìn)行復(fù)合的各種管理員,我們?cè)诖a中做一下特殊判斷即可。下面是spring aop的配置文件配置方法。
<bean id="usersPermissionsAdvice" class="com.thundersoft.metadata.aop.UsersPermissionsAdvice"/> <aop:config> <!--定義切面 --> <aop:aspect id="authAspect" ref="usersPermissionsAdvice"> <!-- 定義切入點(diǎn) (配置在com.thundersoft.metadata.web.controller下所有的類在調(diào)用之前都會(huì)被攔截) --> <aop:pointcut expression="(execution(* com.thundersoft.metadata.web.controller.*.add*(..)) or execution(* com.thundersoft.metadata.web.controller.*.edit*(..)) or execution(* com.thundersoft.metadata.web.controller.*.del*(..)) or execution(* com.thundersoft.metadata.web.controller.*.update*(..)) or execution(* com.thundersoft.metadata.web.controller.*.insert*(..)) or execution(* com.thundersoft.metadata.web.controller.*.modif*(..))) or execution(* com.thundersoft.metadata.web.controller.*.down*(..))) and ( !execution(* com.thundersoft.metadata.web.controller.FindPasswordController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.SelfServiceController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.HomeController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.UserStatusController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.DashboardController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.MainController.*(..))))" id="authPointCut"/> <!--方法被調(diào)用之前執(zhí)行的 --> <aop:before method="readOnly" pointcut-ref="authPointCut"/> </aop:aspect> </aop:config>
只讀管理員權(quán)限管理代碼實(shí)現(xiàn)
上面說(shuō)了那么多,廢話不多說(shuō)了,下面是對(duì)只讀權(quán)限與各種復(fù)合權(quán)限進(jìn)行控制的切面代碼實(shí)現(xiàn)。
/** * 對(duì)只讀管理員以及其復(fù)合管理員進(jìn)行aop攔截判斷. * @param joinPoint 切入點(diǎn). * @throws IOException */ public void readOnly(JoinPoint joinPoint) throws IOException { /** * 獲取被攔截的方法. */ String methodName = joinPoint.getSignature().getName(); /** * 獲取被攔截的對(duì)象. */ Object object = joinPoint.getTarget(); logger.info("權(quán)限管理aop,方法名稱" + methodName); HttpServletRequest request =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpServletResponse response =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); String roleFlag = GetLoginUserInfor.getLoginUserRole(request); /** * 超級(jí)管理員 */ if (PermissionsLabeled.super_Admin.equals(roleFlag)) { return; } /** * 只讀管理員做數(shù)據(jù)更改權(quán)限的判斷 */ if (PermissionsLabeled.reader_Admin.equals(roleFlag)) { logger.error("只讀管理員無(wú)操作權(quán)限!"); response.sendRedirect(request.getContextPath() + "/auth/readOnly"); } /** * 部門管理員,且為只讀管理員, */ if (PermissionsLabeled.dept_reader_Admin.equals(roleFlag)) { if (object instanceof DepartmentController) { return; } if (object instanceof UserController) { if (methodName.contains("addAdmin")) { response.sendRedirect(request.getContextPath() + "/auth/readOnly"); } if (methodName.contains("deleteAdmin")) { response.sendRedirect(request.getContextPath() + "/auth/readOnly"); } if (methodName.contains("updateAdmin")) { response.sendRedirect(request.getContextPath() + "/auth/readOnly"); } return; } if (object instanceof GroupController) { return; } logger.error("部門管理員,且為只讀管理員無(wú)操作權(quán)限!"); response.sendRedirect(request.getContextPath() + "/auth/readOnly"); } /** * 應(yīng)用管理員,且為只讀管理員 */ if (PermissionsLabeled.app_reader_Admin.equals(roleFlag)) { if (object instanceof AppController) { return; } if (object instanceof AppPolicyController) { return; } logger.error("應(yīng)用管理員,且為只讀管理員無(wú)操作權(quán)限!"); response.sendRedirect(request.getContextPath() + "/auth/readOnly"); } /** * 部門管理員,且為應(yīng)用管理員,且為只讀管理員 */ if (PermissionsLabeled.dept_app_reader_Admin.equals(roleFlag)) { if (object instanceof DepartmentController) { return; } if (object instanceof UserController) { return; } if (object instanceof GroupController) { return; } if (object instanceof AppController) { return; } if (object instanceof AppPolicyController) { return; } logger.error("部門管理員,且為應(yīng)用管理員,且為只讀管理員無(wú)操作權(quán)限"); response.sendRedirect(request.getContextPath() + "/auth/readOnly"); } }
具有專門功能的管理員權(quán)限控制的切點(diǎn)選擇
因?yàn)榫哂袑iT的管理員權(quán)限比較特殊,樓主采用的方式除了通用訪問(wèn)權(quán)限之外的controller全切,特殊情況在代碼邏輯里面做實(shí)現(xiàn)即可。配置文件代碼如下:
<aop:config> <!--定義切面 --> <aop:aspect id="authAspect" ref="usersPermissionsAdvice"> <!-- 定義切入點(diǎn) (配置在com.thundersoft.metadata.web.controller下所有的類在調(diào)用之前都會(huì)被攔截) --> <aop:pointcut expression="(execution(* com.thundersoft.metadata.web.controller.*.*(..)) and ( !execution(* com.thundersoft.metadata.web.controller.FindPasswordController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.SelfServiceController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.HomeController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.UserStatusController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.DashboardController.*(..)) and !execution(* com.thundersoft.metadata.web.controller.MainController.*(..))))" id="appAuthPointCut"/> <!--方法被調(diào)用之前執(zhí)行的 --> <aop:before method="appDeptAuth" pointcut-ref="appAuthPointCut"/> </aop:aspect> </aop:config>
##權(quán)限管理的切面代碼實(shí)現(xiàn)
/** * 對(duì)應(yīng)用管理員以及部門管理員進(jìn)行aop攔截判斷. * @param joinPoint 切入點(diǎn). * @throws IOException */ public void appDeptAuth(JoinPoint joinPoint) throws IOException { /** * 獲取被攔截的方法. */ String methodName = joinPoint.getSignature().getName(); /** * 獲取被攔截的對(duì)象. */ Object object = joinPoint.getTarget(); logger.info("權(quán)限管理aop,方法名稱",methodName); HttpServletRequest request =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpServletResponse response =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); String roleFlag = GetLoginUserInfor.getLoginUserRole(request); /** * 超級(jí)管理員 */ if (PermissionsLabeled.super_Admin.equals(roleFlag)) { return; } /** * 應(yīng)用管理員做數(shù)據(jù)更改權(quán)限的判斷 */ if (PermissionsLabeled.app_Admin.equals(roleFlag)) { if (object instanceof AppController) { return; } if (object instanceof AppPolicyController) { return; } logger.error("應(yīng)用管理員無(wú)操作權(quán)限"); response.sendRedirect(request.getContextPath() + "/auth/readOnly"); } else if (PermissionsLabeled.dept_Admin.equals(roleFlag)) { if (object instanceof DepartmentController) { return; } if (object instanceof UserController) { return; } if (object instanceof GroupController) { return; } if ("getAllDepartments".equals(methodName)) { return; } logger.error("應(yīng)用管理員無(wú)操作權(quán)限"); response.sendRedirect(request.getContextPath() + "/auth/readOnly"); } else { return; } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)站欄目:springaop實(shí)現(xiàn)用戶權(quán)限管理的示例
分享網(wǎng)址:http://jinyejixie.com/article14/ggigge.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站建設(shè)、定制開(kāi)發(fā)、網(wǎng)站導(dǎo)航、網(wǎng)站維護(hù)、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)