Introduction au CSRF
CSRF (contrefaçon de demande inter-sites), nom chinois: contrefaçon de demande croisée, également connue sous le nom de: un clic attaque / session, abréviation: CSRF / xsrf.
Pour des introductions spécifiques et des méthodes d'attaque de SCRF, veuillez vous référer à l'introduction de Baidu Encyclopedia et à l'analyse d'un grand gars:
L'encyclopédie CSRF Baidu discute brièvement des méthodes d'attaque CSRF
Étapes de configuration
1. Dépendre le package JAR
<Properties> <printemps.security.version> 4.2.2.release </sspring.security.version> </properties> <dependency> <proupId> org.springframework.Security </proupId> <Artifactid> Spring-Sécurité-core </ artifactid> <version> $ {printemps.security.version} </ version> </ dépendance>> $. <GroupId> org.springFramework.Security </proupId> <Ertifactid> Spring-Securecurity-web </letefactId> <DERSE> $ {Spring.Security.SpringFramework.Security </roulid> <ArtifActid> Spring-SECURY-CONFIG <version> $ {printemps.security.version} </ version> </dependency> 2.Web.xml Configuration
<filter> <filter-name> springSecurityFilterChain </ Filter-Name> <Filter-Class> org.springFramework.web.filter.delegatingFilterProxy </ Filter-Class> </filter> <filter-Mapping> <Filter-Name> SpringSecureFilterChain </filter-name> <url-sattern> / * </ url-stern> </ filter-mapping>
3. Configuration du fichier de configuration de ressort
<bean id = "csrfsecurityRequestmatcher"> </ank> <Security: http auto-config = "true" use-expressions = "true"> <securit </ Sécurité: http>
4. Personnalisez la classe d'implémentation de requestmatcher csrfsecurityRequestmatcher
Cette classe est utilisée pour personnaliser les demandes qui ne nécessitent pas d'interception et de filtrage. Si le CSRF est configuré, toutes les demandes HTTP sont interceptées par CSRFFILTER, et il existe une classe privée DefaultRequiRessrfmatcher dans CSRFFILTER.
Code source 1: Classe DefaulTRequiRessrfmatcher
Classe finale statique privée DefaulTeQueResSrfmatcher implémente demandematcher {private final hashset <string> allowerMethods; privé defaulTrEquiReRsSrfMatcher () {this.AllowedMethods = new HashSet (arrays.aslist (new String [] {"get", "head", "trace", "options"})); } public booléen Matches (requête httpsservletRequest) {return! this.allowedMethods.Contains (request.getMethod ()); }} À partir de ce code source, nous pouvons constater que la méthode post est exclue, c'est-à-dire que seuls les quatre types de méthodes tels que GET | head | trace | Les options seront publiées. Les demandes HTTP d'autres méthodes doivent vérifier si le jeton _CSRF est correct. Habituellement, lorsque vous appelez le service d'interface de repos dans la méthode post, il n'y a pas de jeton _CSRF, ce qui entraînera l'échec de notre interface de repos. Nous devons personnaliser une classe pour libérer l'interface de ce type. Jetons un coup d'œil à nos filtres personnalisés:
Code source 2: CSRFSECURITYREQUESTMATCHER
La classe publique CSRFSecurityRequestMatcher implémente demandeur {Private Pattern allowingMethods = Pattern.Compile ("^ (get | head | trace | options) $"); privé regexRequestmatcher non protégématcher = new regexRequestmatcher ("^ / rest /.*", null); @Override public boolean Matches (httpsservletRequest request) {if (allowerMethods.matcher (request.getMethod ()). Matches ()) {return false; } return! non protégématcher.matches (demande); }} Remarque: Généralement, les services d'interface de repos que nous définissons sont tous avec / repos /, donc si votre projet n'est pas utilisé, ou qu'il n'y a pas de service de repos dans le projet, cette classe peut être complètement omise.
5. Configuration de la demande de postes
Généralement, il existe un fichier JSP commun dans notre projet, qui est référencé par chaque page, nous pouvons donc effectuer la configuration suivante dans le fichier commun:
<meta name = "_ csrf" contenu = "$ {_ csrf.token}" /> <meta name = "_ csrf_header" contenu = "$ {_ csrf.HEADERNAME}" /> <cript> var token = "contenu"); var en-tête = $ ("meta [name = '_ csrf_header']"). attr ("contenu"); $ .ajaxSetUp ({beforesend: function (xhr) {if (header && token) {xhr.setRequestHeader (en-tête, token);}}}); </cript> $ .ajaxsetup signifie ajouter cet en-tête et ce token à toutes nos demandes, ou le mettre dans le formulaire. Notez que _CSRF doit correspondre à la configuration dans le fichier de configuration de Spring Security, et la valeur par défaut est _CSRF.
Analyse du code source
Nous savons que puisque CSRF est configuré, toutes les demandes HTTP seront interceptées par CSRFFILTER, donc après avoir examiné le code source de CSRFFILTER, vous serez clair sur le principe en un coup d'œil. Ici, nous ne regardons que la méthode de filtrage spécifique:
Code source 3: Méthode DoFilteRinternal de CSRFFILTER
VOID DOFILTERInternal protégé (demande HttpServletRequest, réponse httpservletResponse, filterChain FilterChain) lève ServletException, ioException {request.setAttribute (httpservletResponse.class.getName (), réponse); Csrftoken csrftoken = this.tokenRepository.loadToken (demande); booléen manquanttoken = csrftoken == null; if (manquingToken) {// Si le jeton est vide, cela signifie que la première fois que vous y accédez, générez un objet de jeton csrftoken = this.tokenRepository.GenerateToken (demande); this.tokenRepository.savetoken (csrftoken, demande, réponse); } request.setAttribute (csrftoken.class.getName (), csrftoken); // Mettez l'objet token dans la demande, notez que la clé ici est csrftoken.getParametername () = _csrf, nous l'écrivons donc à mort sur la page. request.setAttribute (csrftoken.getParametername (), csrftoken); // Cette machine est le filtre que nous personnalisons dans le fichier de configuration de Spring, c'est-à-dire, obtenez, tête, trace, options et nos repos ne gèrent pas if (! This.requirecsrfprotectionmatcher.matches (request)) {filterchain.dofilter (request, réponse); } else {String actualToken = request.GetHeader (csrftoken.geTheadername ()); if (actualToken == null) {actualToken = request.getParameter (csrftoken.getParametername ()); } if (! csrftoken.getToken (). equals (acalToken)) {if (this.logger.isdebugeNabled ()) {this.logger.debug ("token csrf invalide trouvé pour" + urlutils.buildfullrequestUrl (request)); } if (MissingToken) {this.AccessdeniedHandler.Handle (demande, réponse, new MissingCsrftOKenexception (actualToken)); } else {this.AccessdenedHandler.handle (demande, réponse, new invalidcsrftoKenexception (csrftoken, actualtoken)); }} else {filterchain.dofilter (request, réponse); }}}Comme on peut le voir à partir du code source, les demandes de poste autres que nos filtres personnalisées nécessitent une vérification des jetons.
À l'origine, je voulais prendre une capture d'écran pour obtenir un cas, puis utiliser le point d'arrêt pour voir l'état de transmission de valeur de la page et l'arrière-plan ... Cependant, je ne peux pas télécharger de photos ici et devenir fou. Ok, tellement à résumer! Si vous avez une mauvaise écriture ou que vous avez d'autres questions, vous pouvez laisser un message pour communiquer.
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.