Ada banyak cara untuk menerapkan verifikasi izin fungsional. Salah satunya adalah menggunakan pencegat untuk mencegat permintaan, dan yang lainnya adalah menggunakan AOP untuk melempar pengecualian.
Pertama, gunakan pencegat untuk mewujudkan fungsi melompat ke antarmuka login ketika tidak masuk. Perhatikan bahwa AOP tidak digunakan di sini, tetapi pencegat dicegat, karena AOP umumnya memasuki metode lapisan layanan, dan pencegat mencegat permintaan dari lapisan pengontrol. Ini juga merupakan prosesor itu sendiri, yang dapat secara langsung mengganggu pengalihan permintaan dan mengembalikan tampilan, sementara AOP tidak bisa.
1. Gunakan pencegat untuk mewujudkan fungsi melompat ke antarmuka login saat tidak masuk
1.1 Interceptor SecurityInterceptor
Paket com.jykj.demo.filter; import java.io.printwriter; import javax.servlet.http.httpservletrequest; javax.servlet.http.httpsession; impor org.springframework.web.servlet.handlerinterceptor; impor org.springframework.web.servlet.modelandview; import com.alibaba.fastjson.json; impor com.jykj.demo.alibaba com.jykj.demo.util.result; kelas publik SecurityInterceptor mengimplementasikan handlerInterceptor {@Override public boolean prehandle (permintaan httpservletrequest, respons httpservletResponse, penangan objek) melempar pengecualian { System.out.println ("SecurityInterceptor:"+request.getContextPath ()+","+request.getRequesturi ()+","+request.getMethod ()); Httpsession sesi = request.getSession (); if (session.getAttribute (helper.session_user) == null) {System.out.println ("OtorisasiException: tidak masuk!" +request.getMethod ()); if ("POST" .EQUALSIGNECASE (request.getMethod ())) {response.setContentType ("Teks/html; charset = utf-8"); Printwriter out = response.getWriter (); out.write (json.tojsonstring (hasil baru (false, "tidak masuk!")))); 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 Metode yang Dibebaskan Otomatis Stub}}1.2.spring-mvc.xml (bagian konfigurasi interceptor)
<!-Menangani http mendapatkan permintaan untuk/sumber daya/** dengan secara efisien melayani sumber daya statis di $ {WebApproot}/Direktori Sumber Daya-> <mvc: mapping sumber daya = "/sumber daya/**" Lokasi = "/Sumber Daya/" untuk Path = "-Path ="-Path/Lokasi Singel " seperti/tes/login-> <mvc: mapping path = "/**/*. aspx"/> <!-Permintaan intersep dengan sufiks .aspx-> <mvc: mapping path = "/**/*. do"/> <!-Path/Login/Login (> <Mvc: MIGMCT/LOGINE/LOGINE/LOGINE/LOGINE/LOGINE/LOGINE/LOGINE/LOGINE. <MVC: Path-Mapping Path = "/Register"/> <Bean> </tean> </mvc: Interceptor> </mvc: Interceptors>Penting untuk ditentukan di sini: jalur yang dicegat oleh pencegat lebih disukai dengan nama akhiran, jika tidak beberapa file sumber daya statis akan sulit dikendalikan, yaitu, permintaan harus memiliki format terpadu seperti .do, dll., Sehingga kecepatan yang cocok dan penyaringan akan sangat cepat. Jika ini bukan masalahnya, misalnya menggunakan /** untuk mencegat semua permintaan, kecepatan rendering halaman akan sangat lambat karena file sumber daya juga dicegat.
2. Gunakan AOP untuk mengimplementasikan verifikasi izin fungsional
Verifikasi izin fungsi juga dapat diimplementasikan secara serupa dengan pencegat, tetapi akan mencegat semua permintaan dan tidak memiliki fungsi penyaringan yang baik untuk permintaan yang tidak memerlukan verifikasi izin. Oleh karena itu, diimplementasikan dengan menggunakan AOP untuk menentukan metode mencegat verifikasi yang diperlukan.
2.1 Izinaspect
Paket com.jykj.demo.filter; impor java.io.ioexception; impor java.lang.reflect.method; impor org.aspectj.lang.joinpoint; impor org.aspectj.lang.reflect.methodsignature; impor org.springframework.bannoCory com.jykj.demo.annotation.validatePermission; impor com.jykj.demo.exception.accessdeniedException; impor com.jykj.demo.service.sysuserrolePermservice;/** bagian log acara, setiap pengontrol dengan @validateSpermission dan @revissionsmissionson. * Jika tidak ada izin, pengecualian ExcessDenIdException dilemparkan, yang meneruskan permintaan ke pengontrol, dan kemudian mengembalikan hasil pengecualian * @Author Administrator * */Izin kelas publik {@Autowired sysuserrolePermservice sysuserrolePermservice; public void dobefore (joinpoint jp) melempar ioException {System.out.println ("log izinaspect sebelum metode:" + jp.getTarget (). getName (). getName () + "." + jp.getSignature (). getName ()); Metode maafmethod = getSourcemethod (jp); if (soruceMethod! = null) {validatePermission opera = sorrymethod.getAnnotation (validatePerMission.class); if (oper! = null) {int fidx = opera.idx (); Objek [] 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; // normal}}}} lempar accessDeniedException baru ("Anda tidak memiliki izin untuk beroperasi!"); } Metode pribadi getSourCeMethod (joinpoint jp) {Method proxymethod = ((Methodyignature) jp.getSignature ()). getMethod (); coba {return jp.getTarget (). getClass (). getMethod (proxymethod.getName (), proxymethod.getParametertypes ()); } catch (nosuchmethodeException e) {e.printstacktrace (); } catch (SecurityException e) {E.PrintStackTrace (); } return null; }}2.2 Anotasi Khusus Penerimaan
Paket com.jykj.demo.annotation; impor java.lang.annotation.Documented; impor java.lang.annotation.elementtype; impor java.lang.annotation.Retensi; tag-tag-tag @notation. anotasi. Metode yang dianotasi oleh anotasi ini memerlukan verifikasi izin* /@target (value = elementType.method) @retention (value = retentionPolicy.runtime) @documentedpublic @interface validatePermission { /** ** @description. dilakukan */ int idx () default 0;}Catatan: AOP memotong metode, bukan permintaan dari pengontrol, sehingga tidak dapat langsung kembali ke tampilan untuk mengganggu permintaan metode, tetapi tujuan mengganggu pelaksanaan metode dapat dicapai dengan melemparkan pengecualian. Oleh karena itu, dalam pemberitahuan sebelumnya, jika Anda secara langsung mengembalikan metode titik koneksi dikembalikan melalui verifikasi, jika tidak, pengecualian khusus AccessDenException akan dilemparkan untuk mengganggu eksekusi metode titik koneksi. Penangkapan pengecualian dapat ditangkap dan dialihkan ke tampilan atau permintaan melalui penangan pengecualian sistem (yang dapat dianggap sebagai pengontrol). Ini mencapai tujuan mencegat permintaan. Oleh karena itu, prosesor pengecualian perlu dikonfigurasi.
2.3 Spring-MVC.XML (Konfigurasi Prosesor Pengecualian, dan Konfigurasi AOP)
<bean> <!-<name properti = "defaulterrorview" value = "rediret:/error"> </property>-> <properti name = "ExceptionMappings"> <sops> <!-<prop key = "com.jykj.demo.exception.AuthoritasionEcception"> Redirect:/Login/LoGin.Exception. key="com.jykj.demo.exception.AccessDeniedException">forward:/accessDenied</prop> </props> </property> </bean><bean id="aspectPermission" /> <!-- Perform function permission verification on all methods of the controller package and its subpackage with @ValidatePermission and ResponseBody annotations--> <aop:config proxy-target-class = "true"> <aop: aspek ref = "aspectPerMission"> <aop: pointcut id = "pc" ekspresi = " @annotation (com.jykj.demo.annotation.validatePermission) dan @annotation (org.springframework.web.nind.annotation.annotation com.jykj.demo.controller ..*.*(..)) "/> <aop: sebelum pointcut-ref =" pc "method =" dobefore "/> </aop: aspek> </aop: config>
2.4 Anotasi permintaan pengontrol yang memerlukan verifikasi fungsional
@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; coba {if (helper.f_action_create.equals (action)) {rs = moduleService.access (module, helper.db_action_insert); //module.setModuleID(rs); Modul = ModuleService.SelectByPrimaryKey (RS); } else if (helper.f_action_edit.equals (action)) {rs = moduleService.access (module, helper.db_action_update); Modul = ModuleService.SelectByPrimaryKey (Module.GetModuleID ()); } else if (helper.f_action_remove.equals (action)) {rs = moduleService.access (module, helper.db_action_delete); } else {return json.toJsonstring (hasil baru (false, "Permintaan Parameter Kesalahan: Tindakan")); }} catch (Exception e) {e.printstacktrace (); return json.tojsonstring (hasil baru (false, "operasi gagal, terjadi pengecualian, silakan hubungi administrator!")); } if (rs <0) {return json.toJsonstring (hasil baru (false, "operasi gagal, silakan hubungi administrator!")); } return json.toJsonstring (hasil baru (true, module)); }2.5 Permintaan pengontrol ke depan:/diakses oleh penangan pengecualian maju:/diakses
@RequestMapping (value = "/AccessDenied", menghasilkan = "text/html; charset = utf-8")@responseBodypublic string AccessDenied () {return json.tojsonstring (hasil baru (false, "Anda tidak memiliki izin untuk beroperasi pada ini!"));}2.6 Ketika verifikasi permintaan gagal, pengontrol di atas mengembalikan hasilnya sendiri.
Seperti yang ditunjukkan di bawah ini:
{"Info": "Anda tidak memiliki izin untuk beroperasi pada ini!", "Sukses": false}
2.7 Contoh Layanan Verifikasi Fungsi
/ *** Verifikasi izin dari pengguna saat ini dalam fungsi tertentu dari modul* @param functionId* @return Sebuah string kosong menunjukkan izin, jika tidak itu adalah pesan kesalahan* @throws Exception*/ Public String IzinValidate (int functionId) {objek o = request.getSession (). GetAttribute (helper.session_user); // if (o == null) lempar otorisasi baru (); SYSUSER LOGINUSER = (SYSUSER) O; if (loginuser.getUserId () == 1) return ""; coba {return mapper.permissionValidate (loginUser.getUserId (), functionId); } catch (exception ex) {ex.printstacktrace (); kembalikan "Pengecualian terjadi dalam operasi basis data!"; }} Catatan: Di sini kita hanya memotong semua metode paket pengontrol dan subpackage dengan @ValidatePermission dan anotasi @ResponseBody. Ini jelas tidak cukup universal. Kita harus memotong metode dengan @ValidatePerMisi. Di kelas bagian, kami akan melempar pengecualian yang berbeda dengan menilai apakah metode tersebut memiliki anotasi @ResponseBody. Jika pengecualian di atas dilemparkan, pengecualian di atas dilemparkan dan dikembalikan ke string JSON.
Kalau tidak, pengecualian khusus lainnya harus dilemparkan dan permintaan dialihkan ke tampilan hukum seperti error.jsp.
Kirim /ModuleAccess.do Permintaan melalui klien. Metode permintaan yang sesuai memiliki @ValidatePermission dan @ResponseBody, dan memiliki parameter ID fungsi FID, sehingga AOP dapat memasukkan metode ini, menjalankan pemberitahuan Dobefore, dan menggunakan parameter fungsi FID untuk memverifikasi izin dalam kombinasi dengan ID pengguna. Jika verifikasi dilewati, program akan terus melaksanakannya. Kalau tidak, pengecualian khusus diakses Exception dilemparkan. Pengecualian ditangkap oleh sistem (penangan pengecualian perlu dikonfigurasi) dan permintaan dikeluarkan maju:/diakses, dan pengontrol/akses yang sesuai menangani permintaan dan mengembalikan JSON yang berisi informasi kegagalan verifikasi kepada klien. Ini mengirimkan permintaan /ModuleAccess.do. Jika verifikasi gagal, teruskan permintaan /diakses, jika tidak, itu akan dieksekusi secara normal. Itu terwujud setelah berkeliling lingkaran besar.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.