J'utilise le printemps 4.3.12.Release version, angularjs 1.4.8. J'essaie d'empêcher l'attaque du CSRF sur l'application.
package com.leadwinner.sms.config.filters; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.access.AccessDeniedHandlerImpl; import org.springframework.web.filter.OncePerRequestFilter; public class StatelessCSRFFilter extends OncePerRequestFilter { private static final String CSRF_TOKEN = "CSRF-TOKEN"; private static final String X_CSRF_TOKEN = "X-CSRF-TOKEN"; private final AccessDeniedHandler accessDeniedHandler = new AccessDeniedHandlerImpl(); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { List<String> excludedUrls = new ArrayList<>(); excludedUrls.add("/resources"); excludedUrls.add("/j_spring_security_check"); excludedUrls.add("/j_spring_security_logout"); excludedUrls.add("/login"); excludedUrls.add("/logout"); excludedUrls.add("/mobile"); excludedUrls.add("/migrate"); excludedUrls.add("/dashboard"); String path = request.getServletPath(); System.out.println(path); AtomicBoolean ignoreUrl = new AtomicBoolean(false); excludedUrls.forEach(url -> { if (request.getServletPath().startsWith(url.toLowerCase()) || request.getServletPath().equals("/")) { ignoreUrl.set(true); } }); if (!ignoreUrl.get()) { final String csrfTokenValue = request.getHeader(X_CSRF_TOKEN); final Cookie[] cookies = request.getCookies(); System.out.println("**************************************************"); System.out.println("--------------------------------------------------"); String csrfCookieValue = null; if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals(CSRF_TOKEN)) { csrfCookieValue = cookie.getValue(); } } } System.out.println("csrfTokenValue = "+csrfTokenValue); System.out.println("csrfCookieValue = "+csrfCookieValue); System.out.println("--------------------------------------------------"); System.out.println("**************************************************"); if (csrfTokenValue == null || !csrfTokenValue.equals(csrfCookieValue)) { accessDeniedHandler.handle(request, response, new AccessDeniedException( "Missing or non-matching CSRF-token")); return; } } filterChain.doFilter(request, response); } }
3 Réponses :
Si la demande peut être apportée par le navigateur et les informations d'identification automatiquement (Cookie de session, crédités d'authentification de base), la protection CSRF est nécessaire, même avec une API mobile.
étant donné que vous avez une API mobile comme une partie de la demande, la question est que ces API soient traitées avec succès par le navigateur? p>
Que je recommanderais est que vous créez deux chaînes de filtres distinctes, comme vous, une pour l'application Web et une pour L'API mobile: p> Qu'est-ce que cela atteint, il sépare les deux configurations. Les points d'extrémité relatives à l'application Web utilisent une configuration et les points d'extrémité relative à l'API mobile utilisent une autre configuration. P> Maintenant, quelques commentaires sur l'API mobile. Je suppose que vous vous authentifiez à l'aide de jetons au porteur OAuth 2.0, c'est pourquoi la configuration ci-dessus utilise mais, puisque vous utilisez Spring Security 4.3, vous devrez peut-être faire quelque chose de plus comme ce qui suit (sauf si vous ne pouvez pas mettre à niveau): P> oauth2resourceserver () code> à partir de la sécurité du ressort 5.1+. Ce que cela désactive sélectivement le CSRF pour les demandes contenant une autorisation
: support xyz code>. p>
@Order(101)
public class MobileApiConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
http
.requestMatchers()
.antMatchers("/api/**")
.and()
.authorizeRequests()
// ...
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(NEVER)
.and()
.addFilterBefore(new MyMobileAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.csrf().disable();
}
}
1. L'API mobile, nous n'incluons pas dans cette configuration, il existe un mobileSessionAspector qui intercepte toutes les API liées au mobile où nous recherchons une autorisation de jeton JWT. 2. J'utilise déjà MULTHTTTPSecurity config. Stackoverflow.com/Questtions/58231064/...
3. Tout ce que j'ai besoin de faire ici consiste à activer le CSRF au printemps et à l'angularjs afin que toutes les demandes (API) et la fonctionnalité de déconnexion soient protégées de l'attaque CSRF et une option pour moi de spécifier la liste des modèles pouvant être utilisés. exclu de la protection de la CSRF.
`hi shiva,
Votre code dans la méthode de configuration de SecurityConfig doit ressembler au code ci-dessous: p> et dans l'aspectcsrffilter, utilisez le code suivant: p>
Pouvez-vous définir la méthode CSRFFILTER (motifs) aussi?
<pre> Add this code for the csrfTokenRepository method private CsrfTokenRepository csrfTokenRepository() { HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); repository.setHeaderName("X-XSRF-TOKEN"); return repository; } Add this for the csrfFilter method private Filter csrfFilter(String[] patterns) { CsrfFilter csrfFilter = new CsrfFilter(csrfTokenRepository()); csrfFilter.setRequireCsrfProtectionMatcher(csrfProtectionMatcher(patterns)); return csrfFilter; } Add this for the csrfProtectionMatcher method private NoAntPathRequestMatcher csrfProtectionMatcher(String[] patterns) { return new NoAntPathRequestMatcher(patterns); } Also remove these lines in configure method .csrfTokenRepository(csrfTokenRepository()) .requireCsrfProtectionMatcher(csrfProtectionMatcher(patterns)) Move these lines below .csrf() in configure method: .and() .addFilterAfter(csrfFilter(patterns), FilterSecurityInterceptor.class) </pre>
Je suis un peu confus car vous semblez utiliser la protection CSRF de Spring Security (câblage d'un CSRFTokenRepository) tout en désactivant la protection (CSRF (). Désactiver ()). En outre, vous écrivez votre propre filtre CSRF. Voulez-vous clarifier si vous essayez d'écrire votre propre protection CSRF? Et si oui, pourquoi est-il fourni par la sécurité de printemps insuffisant?
Pardon. Cela a été commenté. Je dois utiliser le mode de protection du ressort de la protection CSRF uniquement, avec le CSRF désactivé pour certaines API mobiles. Étant donné que je ne pouvais pas faire cela, j'ai essayé une solution alternative d'angular Ajout du jeton CSRF dans l'en-tête et le cookie à travers l'intercepteur angulaire, qui fonctionnait bien, à l'exception de la page de déconnexion, car pour la déconnexion, HREF est utilisé. Toute aide pour permettre la protection de la CSRF au printemps avec lequel je peux désactiver la vérification du CSRF de l'API mobile suffirait.