web-dev-qa-db-fra.com

Sécurité Spring: Activer/Désactiver CSRF par type de client (navigateur/non-navigateur)

La doc du printemps dit 

"Lorsque vous utilisez la protection CSRF? Notre recommandation est d'utiliser la protection CSRF pour toute demande pouvant être traitée par un navigateur par des utilisateurs normaux. Si vous créez uniquement un service utilisé par des clients autres que des navigateurs, vous souhaiterez probablement la désactiver. Protection CSRF. " 

Que se passe-t-il si mon service doit être utilisé à la fois par des clients "navigateurs" et "non-navigateurs" tels que des services externes tiers? La sécurité de Spring permet-elle de désactiver le CSRF exclusivement pour certains types de clients?

Référence: http://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html

18
Himalay Majumdar

Je suis sûr qu'il existe un moyen de le faire dans Spring Security XML, mais comme j'utilise Java Config, voici ma solution.

 @Configuration
 @EnableWebSecurity
 public class SecurityConfig {

    @Configuration
    @Order(1)
    public static class SoapApiConfigurationAdapter extends WebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher("/soap/**")
                .csrf().disable()
                .httpBasic();
        }
    }


    @Configuration
    public static class WebApiConfigurationAdapter extends WebSecurityConfigurerAdapter {

        protected void configure(HttpSecurity http) throws Exception {
            http        
                .formLogin()
                    .loginProcessingUrl("/authentication")
                    .usernameParameter("j_username")
                    .passwordParameter("j_password").permitAll()
                    .and()
                .csrf().disable()

        }
     }
}
9
Himalay Majumdar

IMHO, il n'y a rien comme ça hors de la boîte. Ce que je ferais dans votre cas, est d’avoir une hiérarchie d’URL par exemple enracinée à /api qui serait exemptée de csrf. C'est facile à configurer. Dans la configuration XML, vous avez un bloc <http> normal comprenant <csrf/>, il vous suffit de le dupliquer et de modifier le premier bloc comme celui-ci.

<http pattern="/api/**">
    ...
    <!-- csrf -->
</http>

Comme c'est le cas en premier, il sera déclenché pour toute demande adressée à /api hierachy sans utiliser csrf, et toutes les autres demandes l'utiliseront.

Dans la partie normale de l'application, vous n'utilisez jamais l'URL /api/** et ne le réservez pas à des utilisations autres que celles du navigateur.

Ensuite, dans vos contrôleurs, vous les associez à leur URL normale et à une copie sous /api:

@Controller
@RequestMapping({ "/rootcontrollerurl", "/api/rootcontrollerurl"})
class XController {
    @RequestMapping(value = "/request_part_url", ...)
    public ModelAndView method() {
        ...
    }
}

(bien sûr, rootcontrollerurl et request_part_url peuvent être vides ...)

Mais vous devez analyser les implications en termes de sécurité de l’autorisation de demandes contrôlées non csrf, et éventuellement exclure les contrôleurs de la hiérarchie /api.

5
Serge Ballesta

Voici ce que j'ai utilisé pour désactiver la protection CSRF sur un noeud final spécifique Sur votre appconfig-security.xml, ajoutez un nœud avec les informations de votre modèle, comme dans l'exemple suivant:

<http security="none" pattern="/sku/*"/>
<http security="none" pattern="/sku/*/*"/>
<http security="none" pattern="/sku"/>

Il suffit de garder à l’esprit que l’ordre est important si vous souhaitez utiliser la commande Toutes les requêtes utilisant le symbole '*' s’appliquent en premier.

1
Jelqui