Il existe de nombreuses façons d'implémenter la vérification de l'autorisation fonctionnelle. L'un consiste à utiliser un intercepteur pour intercepter les demandes, et l'autre consiste à utiliser AOP pour lancer des exceptions.
Tout d'abord, utilisez un intercepteur pour réaliser la fonction de sauter à l'interface de connexion lorsqu'elle n'est pas connectée. Notez que AOP n'est pas utilisé ici, mais les intercepteurs sont interceptés, car AOP entre généralement dans la méthode de la couche de service, et l'intercepteur intercepte la demande de la couche de contrôleur. Il s'agit également d'un processeur lui-même, qui peut interrompre directement le passage de la demande et renvoyer la vue, tandis que AOP ne peut pas.
1. Utilisez l'intercepteur pour réaliser la fonction de sauter à l'interface de connexion lorsqu'il n'est pas connecté
1.1 Interceptor Security Interceptor
package com.jykj.demo.filter; import java.io.printwriter; import javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; javax.servlet.http.httpSession; import org.springframework.web.servlet.handlerinterceptor; import org.springframework.wson; import com.jykj.demo.util.helper; import; com.jykj.demo.util.result; public class SecurityInterceptor implémente handlerInterceptor {@Override public boolean prehandle (httpservletRequest request, httpservletResponse réponse, objet handler) 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: non connecté!" + request.getMethod ()); if ("post" .equalsIrNoreCase (request.getMethod ())) {réponse.setContentType ("text / html; charset = utf-8"); Printwriter out = réponse.getWriter (); out.write (json.tojSontring (nouveau résultat (faux, "non connecté!"))); out.flush (); out.close (); } else {réponse.sendRedirect (request.getContextPath () + "/ login"); } return false; } else {return true; }} @Override public void Posthandle (requête httpservletRequest, réponse httpservletgnation, gestionnaire d'objets, modelAndView ModelAndView) exception {// todo généré par la méthode Auto Stub} @Override public Void AfterCelition (httpsservletrest request, httpserRetresponse Stume de méthode générée automatiquement}}1.2.Spring-mvc.xml (partie de configuration interceptrice)
<! - gère les demandes de GET HTTP pour / ressources / ** en servant efficacement les ressources statiques dans le répertoire $ {webApproot} / Ressources -> <mvc: Ressources mapping = "/ ressources / **" location = "/ ressources /" /> <mvc: interceptors> <mvc: interceptor> <mvc: mapping path = "/ **" /> <- intercept pour une seule demande de lysine Structures telles que / test / connexion -> <mvc: mapping path = "/ ** / *. aspx" /> <! - Intercepter les demandes avec suffixe .aspx -> <mvc: mapping path = "/ ** / *. do" / *. path = "/ Signin" /> <Mvc: excluant la mappage path = "/ registre" /> <an bean> </-bean> </mvc: interceptor> </mvc: intercepteurs>Il est nécessaire de spécifier ici: le chemin intercepté par l'intercepteur est de préférence avec un nom de suffixe, sinon certains fichiers de ressources statiques seront difficiles à contrôler, c'est-à-dire que la demande devrait avoir un format unifié tel que .do, etc., afin que la vitesse de correspondance et de filtrage soit très rapide. Si ce n'est pas le cas, par exemple en utilisant / ** pour intercepter toutes les demandes, la vitesse de rendu de page sera très lente car le fichier de ressources est également intercepté.
2. Utilisez AOP pour implémenter la vérification de l'autorisation fonctionnelle
La vérification de l'autorisation de la fonction peut également être implémentée de manière similaire avec un intercepteur, mais il interceptera toutes les demandes et n'a pas de bonne fonction de filtrage pour les demandes qui ne nécessitent pas de vérification de l'autorisation. Par conséquent, il est implémenté en utilisant AOP pour spécifier la méthode d'interception de la vérification requise.
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.methsignature; import org.springframework.beans.factory.annotation.autowired; import; com.jykj.demo.annotation.validatePermission; import com.jykj.demo.exception.accessdenedException; import com.jykj.demo.service.sysuserrroleperservice; / ** * Section du journal des événements, tout contrôleur avec @Validatepermission et @Ressagebody Annotation Must Pitan Perference Checks. * S'il n'y a pas d'autorisation, une exception AccessEniedException est lancée, qui transmet la demande à un contrôleur, puis renvoie le résultat de l'exception * @Author Administrator * * / public class PermissionAspect {@Autowired SysUserRroleperService SysUserRerlePermService; public void dobefore (joinpoint jp) lève ioException {System.out.println ("Log PermissionAspect avant la méthode:" + jp.getTarget (). getClass (). getName () + "." + jp.getSignature (). getName ()); Méthode désoléMethod = GetSourceMethod (JP); if (soruceMethod! = null) {validerPermission opéra = désoléMethod.getannotation (validatePermission.class); if (oper! = null) {int fidx = opera.idx (); Objet [] args = jp.getargs (); if (fidx> = 0 && fidx <args.length) {int functionId = (Integer) args [fidx]; String rs = sysUserRroleperMService.PermissionValidate (fonctionId); System.out.println ("PermissionValidate:" + rs); if (Rs.trim (). isempty ()) {return; // normal}}}} lance new AccessEniedException ("vous n'avez pas la permission de fonctionner!"); } Méthode privée getSourceMethod (joinpoint jp) {méthode proxymethod = ((Methodsignature) jp.getSignature ()). getMethod (); essayez {return jp.getTarget (). getClass (). getMethod (proxymethod.getName (), proxythod.getParameterTypes ()); } catch (NosuchMethodexception e) {e.printStackTrace (); } catch (SecurityException e) {e.printStackTrace (); } return null; }}2.2 Annotation personnalisée Valider Permission
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 This annotation is a Annotation de type tag. La méthode annotée par cette annotation nécessite une vérification de l'autorisation * / @ cible (valeur = elementType.Method) @retention (value = retenderPolicy.runtime) @DocumentedPublic @Interface ValidatePermission {/ ** * @description effectué * / int idx () par défaut 0;}Remarque: AOP coupe une méthode, pas une demande d'un contrôleur, il ne peut donc pas revenir directement à la vue pour interrompre la demande de la méthode, mais le but d'interrompre l'exécution de la méthode peut être réalisé en lançant des exceptions. Par conséquent, dans la notification avant, si vous renvoyez directement, la méthode du point de connexion est renvoyée par vérification, sinon une exception personnalisée AccessEnedEdException sera lancée pour interrompre l'exécution de la méthode du point de connexion. La capture de l'exception peut être capturée et redirigée vers une vue ou une demande via le gestionnaire d'exceptions du système (qui peut être considérée comme un contrôleur). Cela atteint le but d'intercepter la demande. Par conséquent, un processeur d'exception doit être configuré.
2.3 Spring-Mvc.xml (Configuration du processeur d'exception et configuration AOP)
<an bean> <! - <propriété name = "DefaulterrorView" value = "rediret: / error"> </ propriété> -> <propriété name = "exceptionmapping key = "com.jykj.demo.Exception.AccessdeniedException"> Forward: / AccessDenied </prop> </popts> </ propriété> </Ean> <Bean Id = "AspectPermission" /> <! - Effectuez la vérification de la permission de la fonction sur toutes les méthodes du package de contrôleur et son sous-package avec @ValidAdPermission et Répondrenty annotations -> <aop: Config Proxy-Target " <aop: aspect ref = "aspectPermission"> <aop: Pointcut id = "pc" expression = "@ annotation (com.jykj.demo.annotation.validatePermission) et @annotation (org.springframework.web.bind.annotation.responsebody) et exécution (* com.jykj.Demo.ConTroller .. *. moins
2.4 Annotation des demandes de contrôleur qui nécessitent une vérification fonctionnelle
@RequestMapping (value = "/moduleAccess.do", méthode = requestMethod.post, produmes = "text / html; charset = utf-8") @ResponseBody @ValidatePermision 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.tojSontring (nouveau résultat (false, "Erreur de paramètre de demande: action")); }} catch (exception e) {e.printStackTrace (); return json.tojSontring (nouveau résultat (false, "l'opération a échoué, une exception s'est produite, veuillez contacter l'administrateur!")); } if (rs <0) {return json.tojSontring (nouveau résultat (false, "l'opération a échoué, veuillez contacter l'administrateur!")); } return json.tojSontring (nouveau résultat (true, module)); }2.5 La demande de contrôleur vers l'avant: / AccessEnied par le gestionnaire d'exceptions en avant: / AccessEnied
@Requestmapping (value = "/ accessdenied", produit = "text / html; charset = utf-8") @ réponse string accessorned () {return json.tojssentring (nouveau résultat (false, "vous n'avez pas la permission de fonctionner sur ceci!"));};2.6 Lorsque la vérification de la demande échoue, le contrôleur ci-dessus renvoie le résultat lui-même.
Comme indiqué ci-dessous:
{"info": "Vous n'avez pas la permission d'opérer à ce sujet!", "Success": FAUX}
2.7 Exemple de service de vérification de la fonction
/ ** * Vérifiez l'autorisation de l'utilisateur actuel dans une certaine fonction d'un module * @param functionID * @return Une chaîne vide indique l'autorisation, sinon c'est un message d'erreur * @throws exception * / public String permissionvalidate (int FunctionId) {object o = request.getSession (). GetAtTRribute (helper.session_user); // if (o == null) lancez une nouvelle AutorisationException (); Sysuser Loginuser = (sysuser) o; if (loginuser.getUserId () == 1) return ""; essayez {return mapper.permissionValidate (loginuser.getUserId (), functionId); } catch (exception ex) {ex.printStackTrace (); Retour "Exception s'est produite dans l'opération de base de données!"; }} Remarque: nous ne faisons ici que toutes les méthodes du package de contrôleur et son sous-package avec @ValidAdPermission et @ResponseBody Annotations. Ce n'est certainement pas assez universel. Nous devons couper la méthode avec @ValidatePermission. Dans la classe de section, nous lancerons différentes exceptions en jugeant si la méthode a des annotations @ResponseBody. Si l'exception ci-dessus est lancée, l'exception ci-dessus est lancée et retournée à la chaîne JSON.
Sinon, une autre exception personnalisée doit être lancée et la demande est redirigée vers une vue juridique telle que error.jsp.
Envoyer /ModuleAccess.do demande par le client. La méthode correspondante de la demande a à la fois @ValidAdPermission et @ResponseBody, et a le paramètre ID de fonction FID, afin qu'AOP puisse entrer la méthode, exécuter la notification DOBEFOR et utiliser le paramètre de fonction FID pour vérifier les autorisations informatiques en combinaison avec l'ID utilisateur. Si la vérification est passée, le programme continuera de l'exécuter. Sinon, une exception personnalisée AccessEnedException est lancée. L'exception est capturée par le système (le gestionnaire d'exceptions doit être configuré) et une demande est émise à l'avance: / AccessEnedied, et le contrôleur / accessoire correspondant gère la demande et renvoie un JSON contenant les informations de défaillance de vérification au client. Cela envoie la demande /moduleAccess.do. Si la vérification échoue, transmettez la demande / AccessEnedied, sinon il sera exécuté normalement. Il a été réalisé après avoir contourné un si grand cercle.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.