มีหลายวิธีในการดำเนินการตรวจสอบการอนุญาตการทำงาน หนึ่งคือการใช้ interceptor เพื่อสกัดกั้นการร้องขอและอื่น ๆ คือการใช้ AOP เพื่อโยนข้อยกเว้น
ขั้นแรกให้ใช้ตัวดักเพื่อรับรู้ฟังก์ชั่นของการกระโดดไปยังอินเตอร์เฟสการเข้าสู่ระบบเมื่อไม่ได้เข้าสู่ระบบโปรดทราบว่า AOP ไม่ได้ใช้ที่นี่ แต่การสกัดกั้นจะถูกสกัดกั้นเนื่องจาก AOP เข้าสู่วิธีการให้บริการโดยทั่วไปและสกัดกั้นการร้องขอจากชั้นคอนโทรลเลอร์ นอกจากนี้ยังเป็นโปรเซสเซอร์เองซึ่งสามารถขัดจังหวะการผ่านคำขอและส่งคืนมุมมองโดยตรงในขณะที่ AOP ไม่สามารถ
1. ใช้ interceptor เพื่อรับรู้ฟังก์ชั่นของการกระโดดไปยังอินเตอร์เฟสเข้าสู่ระบบเมื่อไม่ได้เข้าสู่ระบบ
1.1 Interceptor SecurityInterceptor
แพ็คเกจ com.jykj.demo.filter; นำเข้า java.io.printwriter; นำเข้า Javax.servlet.http.httpservletRequest นำเข้า Javax.servlet.http.httpservletResponse; javax.servlet.http.httpsession; นำเข้า org.springframework.web.servlet.handlerinterceptor; นำเข้า org.springframework.web.servlet.modelandview; นำเข้า com.alibaBa.fastjson.json com.jykj.demo.util.result; Public Class SecurityInterceptor ใช้ HandlerInterceptor {@Override Public Boolean Prehandle (httpservletrequest Request, httpservletResponse การตอบสนอง System.out.println ("SecurityInterceptor:"+request.getContextPath ()+","+request.getRequesturi ()+","+request.getMethod ()); httpsession session = request.getSession (); if (session.getAttribute (helper.session_user) == null) {system.out.println ("การอนุญาต Exception: ไม่เข้าสู่ระบบ!" +request.getMethod ()); if ("post" .equalsignorecase (request.getMethod ())) {response.setContentType ("ข้อความ/html; charset = utf-8"); PrintWriter out = response.getWriter (); out.write (json.tojsonstring (ผลลัพธ์ใหม่ (เท็จ, "ไม่ได้เข้าสู่ระบบ!"))); out.flush (); out.close (); } else {response.sendredirect (request.getContextPath ()+"/ล็อกอิน"); } return false; } else {return true; }} @Override โมฆะสาธารณะ posthandle (คำขอ httpservletrequest, httpservletResponse, ตัวจัดการวัตถุ, modelandview modelandview) โยนข้อยกเว้น {// toDo วิธีการที่สร้างขึ้นอัตโนมัติ วิธีการที่สร้างอัตโนมัติ todo stub}}}1.2.Spring-MVC.XML (ส่วนการกำหนดค่า interceptor)
<!-จัดการ http รับคำขอ/ทรัพยากร/** โดยการให้บริการทรัพยากรแบบคงที่อย่างมีประสิทธิภาพในไดเรกทอรี $ {webapproot}/ทรัพยากร-> <mvc: การแมปทรัพยากร = "/ทรัพยากร/**" location = "/"/> โครงสร้างเช่น/ทดสอบ/เข้าสู่ระบบ-> <mvc: เส้นทางการแมป = "/**/*. aspx"/> <!-การสกัดกั้นคำขอด้วยคำต่อท้าย .aspx-> <mvc: เส้นทางการแมป = "/**/*. ทำ"/> path = "/signin"/> <mvc: exclude-mapping path = "/register"/> <bean> </ebean> </mvc: interceptor> </mvc: interceptors>มีความจำเป็นที่จะต้องระบุที่นี่: เส้นทางที่สกัดกั้นโดย interceptor นั้นดีกว่าด้วยชื่อต่อท้ายมิฉะนั้นไฟล์ทรัพยากรคงที่บางไฟล์จะควบคุมได้ยากนั่นคือคำขอควรมีรูปแบบแบบครบวงจรเช่น .DO ฯลฯ เพื่อให้ความเร็วในการจับคู่และการกรองจะเร็วมาก หากนี่ไม่ใช่กรณีเช่นการใช้ /** เพื่อสกัดกั้นคำขอทั้งหมดความเร็วในการเรนเดอร์หน้าจะช้ามากเนื่องจากไฟล์ทรัพยากรถูกสกัดกั้น
2. ใช้ AOP เพื่อดำเนินการตรวจสอบการอนุญาตการทำงาน
การตรวจสอบการอนุญาตฟังก์ชั่นสามารถนำไปใช้ได้เช่นเดียวกันกับตัวดักจับ แต่จะสกัดกั้นการร้องขอทั้งหมดและไม่มีฟังก์ชั่นการกรองที่ดีสำหรับคำขอที่ไม่ต้องการการตรวจสอบการอนุญาต ดังนั้นจึงถูกนำไปใช้โดยใช้ AOP เพื่อระบุวิธีการสกัดกั้นการตรวจสอบที่จำเป็น
2.1 PermissionAspect
แพ็คเกจ com.jykj.demo.filter; นำเข้า java.io.ioexception; นำเข้า java.lang.reflect.method; นำเข้า org.aspectj.lang.joinpoint; นำเข้า org.aspectj.lang.reflect.methodsignature; com.jykj.demo.annotation.validatepermission; นำเข้า com.jykj.demo.exception.accessdeniedexception; นำเข้า com.jykj.demo.service.sysuserrolepermservice; * หากไม่มีการอนุญาตข้อยกเว้นของ AccessDeniedException จะถูกโยนลงไปซึ่งส่งต่อการร้องขอไปยังคอนโทรลเลอร์จากนั้นส่งคืนผลลัพธ์ข้อยกเว้น * @author Administrator * */การอนุญาตคลาสสาธารณะ โมฆะสาธารณะ dobofore (joinpoint jp) พ่น ioexception {system.out.println ("log permissionaspect ก่อนวิธี:" + jp.getTarget (). getClass (). getName () + "." + jp.getSignature () getName (); วิธีการขอโทษที่มีค่า = getSourceMethod (JP); if (sorucemethod! = null) {validatePermission opera = ขออภัยการ getNanotation (varidatePermission.class); if (oper! = null) {int fidx = opera.idx (); Object [] args = jp.getargs (); if (fidx> = 0 && fidx <args.length) {int functionid = (จำนวนเต็ม) args [fidx]; String rs = sysuserrolepermservice.permissionValidate (functionId); System.out.println ("PermissionValidate:"+Rs); if (rs.trim (). isempty ()) {return; // ปกติ}}}} โยน accessDeniedException ใหม่ ("คุณไม่ได้รับอนุญาตให้ทำงาน!"); } วิธีการส่วนตัว getSourceMethod (joinpoint jp) {method proxymethod = ((methodSignature) jp.getSignature ()). getMethod (); ลอง {return jp.getTarget (). getClass (). getMethod (proxymethod.getName (), proxymethod.getParameterTypes ()); } catch (nosuchmethodexception e) {e.printstacktrace (); } catch (SecurityException E) {E.printStackTrace (); } return null; -2.2 คำอธิบายประกอบที่กำหนดเอง
แพ็คเกจ com.jykj.demo.annotation; นำเข้า java.lang.annotation.documented; นำเข้า java.lang.annotation.ElementType; นำเข้า java.lang.annotation.retention; นำเข้า java.lang.annotation.tannotation. คำอธิบายประกอบประเภทแท็ก วิธีการที่มีคำอธิบายประกอบโดยคำอธิบายประกอบนี้ต้องการการตรวจสอบสิทธิ์* /@เป้าหมาย (value = elementType.method) @retention (value = retentionPolicy.runtime) @documentedPublic @interface ValidatePermission { /*** @description ตำแหน่งดัชนีพารามิเตอร์ ไม่สามารถทำได้ */ int idx () ค่าเริ่มต้น 0;}หมายเหตุ: AOP ตัดเป็นวิธีการไม่ใช่คำขอจากคอนโทรลเลอร์ดังนั้นจึงไม่สามารถกลับไปที่มุมมองโดยตรงเพื่อขัดจังหวะการร้องขอของวิธีการ แต่วัตถุประสงค์ของการขัดจังหวะการดำเนินการของวิธีการสามารถทำได้โดยการโยนข้อยกเว้น ดังนั้นในการแจ้งเตือนก่อนหน้านี้หากคุณส่งคืนวิธีการเชื่อมต่อโดยตรงจะถูกส่งคืนผ่านการตรวจสอบมิฉะนั้นจะมีการยกเว้น accessDeniedException แบบกำหนดเองเพื่อขัดจังหวะการดำเนินการของวิธีการเชื่อมต่อ การจับข้อยกเว้นสามารถจับและเปลี่ยนเส้นทางไปยังมุมมองหรือคำขอผ่านตัวจัดการข้อยกเว้นของระบบ (ซึ่งถือได้ว่าเป็นคอนโทรลเลอร์) สิ่งนี้บรรลุวัตถุประสงค์ในการสกัดกั้นคำขอ ดังนั้นต้องกำหนดค่าโปรเซสเซอร์ข้อยกเว้น
2.3 Spring-MVC.XML (การกำหนดค่าโปรเซสเซอร์ข้อยกเว้นและการกำหนดค่า AOP)
<ebean> <!-<property name = "defaulterRorView" value = "Rediret:/error"> </property>-> <property name = "ExceptionMappings"> <props> <!-<prop key = "com.jykj.demo.exception.authorizationException"> key = "com.jykj.demo.exception.accessDeniedException"> ส่งต่อ:/accessDenied </prop> </props> </poreport> </epean> <bean id = "Assumits PperMission"/> <! Proxy-target-class = "true"> <aop: ref = "appitionspermission"> <aop: pointcut id = "pc" expression = " @Annotation (com.jykj.demo.annotation.validatepermission) และ @annotation (org.springframework.web.bind. com.jykj.demo.controller ..*.*(.. )) "/> <aop: ก่อน pointcut-ref =" pc "method =" debofore "/> </aop: แง่มุม> </aop: config>
2.4 คำอธิบายประกอบของคำขอคอนโทรลเลอร์ที่ต้องมีการตรวจสอบการทำงาน
@RequestMapping (value = "/ModuleAccess.do", method = requestMethod.post, ผลิต = "ข้อความ/html; charset = utf-8") @ResponseBody @ValidatePermission สตริงสาธารณะ int rs = -1; ลอง {ถ้า (helper.f_action_create.equals (การกระทำ)) {rs = moduleservice.access (โมดูล, helper.db_action_insert); //module.setModuleid(rs); โมดูล = Moduleservice.SelectByPrimaryKey (RS); } อื่นถ้า (helper.f_action_edit.equals (การกระทำ)) {rs = moduleservice.access (โมดูล, helper.db_action_update); module = moduleservice.selectByPrimaryKey (module.getModuleId ()); } อื่นถ้า (helper.f_action_remove.equals (การกระทำ)) {rs = moduleservice.access (โมดูล, helper.db_Action_Delete); } else {return json.tojsonstring (ผลลัพธ์ใหม่ (เท็จ "ข้อผิดพลาดพารามิเตอร์การร้องขอ: การกระทำ")); }} catch (exception e) {e.printstacktrace (); return json.tojsonstring (ผลลัพธ์ใหม่ (เท็จ "การดำเนินการล้มเหลวมีข้อยกเว้นเกิดขึ้นโปรดติดต่อผู้ดูแลระบบ!")); } if (rs <0) {return json.tojsonstring (ผลลัพธ์ใหม่ (เท็จ "การดำเนินการล้มเหลวโปรดติดต่อผู้ดูแลระบบ!")); } return json.tojsonstring (ผลลัพธ์ใหม่ (จริง, โมดูล)); -2.5 คำขอคอนโทรลเลอร์ไปข้างหน้า:/accessDenied โดย Handler Exception Forward:/AccessDenied
@RequestMapping (value = "/accessDenied", ผลิต = "ข้อความ/html; charset = utf-8")@responsebodypublic accesscontenied () {return json.tojsonstring (ผลลัพธ์ใหม่ (เท็จ "คุณไม่ได้รับอนุญาตให้ดำเนินการนี้!");2.6 เมื่อการตรวจสอบคำขอล้มเหลวคอนโทรลเลอร์ด้านบนจะส่งคืนผลลัพธ์เอง
ดังที่แสดงด้านล่าง:
{"info": "คุณไม่ได้รับอนุญาตให้ทำงานในสิ่งนี้!", "ความสำเร็จ": false}
2.7 ตัวอย่างบริการตรวจสอบฟังก์ชั่น
/ *** ตรวจสอบการอนุญาตของผู้ใช้ปัจจุบันในฟังก์ชั่นบางอย่างของโมดูล* @param functionId* @return สตริงที่ว่างเปล่าระบุการอนุญาตมิฉะนั้นมันเป็นข้อความแสดงข้อผิดพลาด* @throws ยกเว้น*/ การอนุญาตสตริงสาธารณะ // ถ้า (o == null) โยนการอนุญาตใหม่ Exception (); sysuser logginuser = (sysuser) o; if (logginuser.getUserId () == 1) return ""; ลอง {return mapper.permissionValidate (logginuser.getUserId (), functionId); } catch (exception ex) {ex.printstacktrace (); return "ข้อยกเว้นเกิดขึ้นในการดำเนินการฐานข้อมูล!"; - หมายเหตุ: ที่นี่เราเพิ่งตัดเป็นวิธีการทั้งหมดของแพ็คเกจคอนโทรลเลอร์และแพคเกจย่อยด้วย @ValidatePermission และ @ResponseBody Annotations นี่เป็นสากลไม่เพียงพอ เราควรตัดเป็นวิธีการด้วย @ValidatePermission ในคลาสส่วนเราจะโยนข้อยกเว้นที่แตกต่างกันโดยการตัดสินว่าวิธีนี้มีคำอธิบายประกอบ @ResponseBody หรือไม่ หากมีการโยนข้อยกเว้นข้างต้นข้อยกเว้นข้างต้นจะถูกโยนและกลับไปที่สตริง JSON
มิฉะนั้นควรมีข้อยกเว้นที่กำหนดเองอื่นและคำขอจะถูกเปลี่ยนเส้นทางไปยังมุมมองทางกฎหมายเช่น error.jsp
ส่ง /moduleaccess.do คำขอผ่านลูกค้า วิธีการที่สอดคล้องกันของคำขอมีทั้ง @ValidatePermission และ @ResponseBody และมีพารามิเตอร์ ID ฟังก์ชั่น FID เพื่อให้ AOP สามารถป้อนวิธีการดำเนินการการแจ้งเตือน DoBofore และใช้พารามิเตอร์ฟังก์ชั่น FID เพื่อตรวจสอบสิทธิ์ในการใช้ร่วมกับ ID ผู้ใช้ หากผ่านการตรวจสอบโปรแกรมจะดำเนินการต่อไป มิฉะนั้นจะมีการโยนข้อยกเว้นแบบกำหนดเอง ข้อยกเว้นถูกจับโดยระบบ (ต้องกำหนดค่าตัวจัดการข้อยกเว้น) และมีการออกคำขอไปข้างหน้า:/accessDenied และคอนโทรลเลอร์ที่เกี่ยวข้อง/accessDenied จัดการคำขอและส่งคืน JSON ที่มีข้อมูลการตรวจสอบความล้มเหลวไปยังลูกค้า สิ่งนี้ส่งคำขอ /moduleaccess.do หากการตรวจสอบล้มเหลวให้ส่งต่อคำขอ /accessDenied มิฉะนั้นจะดำเนินการตามปกติ มันเป็นจริงหลังจากเดินไปรอบ ๆ วงกลมขนาดใหญ่
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น