web-dev-qa-db-fra.com

Utilisation de ressources Web statiques dans l'application Spring Boot & Spring Security

J'essaie de développer une application Web Spring Boot et de la sécuriser à l'aide de la sécurité de Spring Java configuration.).

Après avoir placé mes ressources Web statiques dans ' src/main/resources/public ' comme conseillé ici dans le blog Spring , je suis capable d'obtenir les ressources statiques. c.-à-d. frapper https://localhost/test.html dans le navigateur sert le contenu HTML.

Problème

Après avoir activé Spring Security, l'URL de la ressource statique doit être authentifiée.

Ma sécurité printanière Java config ressemble à ceci: -

@Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.
            authorizeRequests()
                .antMatchers("/","/public/**", "/resources/**","/resources/public/**")
                    .permitAll()
                .antMatchers("/google_oauth2_login").anonymous()
                    .anyRequest().authenticated()
                .and()
                .formLogin()
                    .loginPage("/")
                    .loginProcessingUrl("/login")
                    .defaultSuccessUrl("/home")
                    .and()
                    .csrf().disable()
                    .logout()
                        .logoutSuccessUrl("/")
                        .logoutUrl("/logout") // POST only
                .and()
                    .requiresChannel()
                    .anyRequest().requiresSecure()
                .and()
                    .addFilterAfter(oAuth2ClientContextFilter(),ExceptionTranslationFilter.class)
                    .addFilterAfter(googleOAuth2Filter(),OAuth2ClientContextFilter.class)
                .userDetailsService(userService);
        // @formatter:on
    }

Comment dois-je configurer antMatchers pour autoriser les ressources statiques placées dans src/main/resources/public?

61
Kumar Sambhav

Il y a plusieurs choses à prendre en compte:

  • Les correspondants Ant correspondent au chemin de la demande et non au chemin de la ressource sur le système de fichiers.
  • Ressources placées dans src/main/resources/public sera servi à partir de la racine de votre application. Par exemple src/main/resources/public/hello.jpg serait servi à partir de http://localhost:8080/hello.jpg

C'est pourquoi votre configuration actuelle de matcher n'a pas autorisé l'accès aux ressources statiques. Pour /resources/** pour fonctionner, vous devez placer les ressources dans src/main/resources/public/resources et y accéder à http://localhost:8080/resources/your-resource.

Lorsque vous utilisez Spring Boot, vous pouvez envisager d’utiliser ses valeurs par défaut plutôt que d’ajouter une configuration supplémentaire. Spring Boot autorisera par défaut l’accès à /css/**, /js/**, /images/**, et /**/favicon.ico. Vous pouvez, par exemple, avoir un fichier nommé src/main/resources/public/images/hello.jpg et sans ajouter de configuration supplémentaire, il serait accessible à http://localhost:8080/images/hello.jpg sans avoir à vous connecter. Vous pouvez le voir en action dans le fichier CSS exemple de sécurité de la méthode Web où l'accès est autorisé au fichier CSS Bootstrap) sans configuration spéciale.

87
Andy Wilkinson
  @Override
      public void configure(WebSecurity web) throws Exception {
        web
          .ignoring()
             .antMatchers("/resources/**"); // #3
      }

Ignorez les requêtes commençant par "/ ressources /". Ceci est similaire à la configuration de http @ security = none lors de l'utilisation de la configuration de l'espace de noms XML.

27
RPaul

Voici la solution ultime, après plus de 20 heures de recherche.

Étape 1. Ajoutez 'MvcConfig.Java' à votre projet.

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
                .addResourceHandler("/resources/**")
                .addResourceLocations("/resources/");
    }
}

Étape 2. Ajouter configure(WebSecurity web) remplacer à votre classe SecurityConfig

@Override
    public void configure(WebSecurity web) throws Exception {
        web
                .ignoring()
                .antMatchers("/resources/**");
    }

Étape 3. Placez toutes les ressources statiques dans webapp/resources /..

20
JasperJ

Cela peut être une réponse (pour la botte de printemps 2) et une question en même temps. Il semble que, au printemps, le démarrage 2 combiné à la sécurité au printemps, tout (qui signifie chaque route/antmatcher) est protégé par défaut si vous utilisez un mécanisme de sécurité individuel étendu de

WebSecurityConfigurerAdapter

Si vous n’utilisez pas de mécanisme de sécurité individuel, tout est comme avant?

Dans les versions plus anciennes de démarrage de printemps (1.5 et moins) comme Andy Wilkinson déclare dans sa réponse ci-dessus, des endroits comme public/** or static/** sont autorisés par défaut.

Donc, pour résumer cette question/réponse: si vous utilisez Spring Boot 2 avec Spring Security et disposez d’un mécanisme de sécurité individuel, vous devez autoriser exclusivement l’accès au contenu statique placé sur n’importe quel itinéraire. Ainsi:

@Configuration
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {

private final ThdAuthenticationProvider thdAuthenticationProvider;

private final ThdAuthenticationDetails thdAuthenticationDetails;

/**
 * Overloaded constructor.
 * Builds up the needed dependencies.
 *
 * @param thdAuthenticationProvider a given authentication provider
 * @param thdAuthenticationDetails  given authentication details
 */
@Autowired
public SpringSecurityConfiguration(@NonNull ThdAuthenticationProvider thdAuthenticationProvider,
                                   @NonNull ThdAuthenticationDetails thdAuthenticationDetails) {
    this.thdAuthenticationProvider = thdAuthenticationProvider;
    this.thdAuthenticationDetails = thdAuthenticationDetails;
}

/**
 * Creates the AuthenticationManager with the given values.
 *
 * @param auth the AuthenticationManagerBuilder
 */
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {

    auth.authenticationProvider(thdAuthenticationProvider);
}

/**
 * Configures the http Security.
 *
 * @param http HttpSecurity
 * @throws Exception a given exception
 */
@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
            .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
            .antMatchers("/management/**").hasAnyAuthority(Role.Role_Engineer.getValue(),
            Role.Role_Admin.getValue())
            .antMatchers("/settings/**").hasAnyAuthority(Role.Role_Engineer.getValue(),
            Role.Role_Admin.getValue())

            .anyRequest()
            .fullyAuthenticated()
            .and()
            .formLogin()
            .authenticationDetailsSource(thdAuthenticationDetails)
            .loginPage("/login").permitAll()
            .defaultSuccessUrl("/bundle/index", true)
            .failureUrl("/denied")
            .and()
            .logout()
            .invalidateHttpSession(true)
            .logoutSuccessUrl("/login")
            .logoutUrl("/logout")
            .and()
            .exceptionHandling()
            .accessDeniedHandler(new CustomAccessDeniedHandler());
}

}

Veuillez faire attention à cette ligne de code, qui est nouvelle:

.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()

Si vous utilisez Spring Boot 1.5 et les versions antérieures, vous n’avez pas besoin d’autoriser explicitement ces emplacements (statique/public/webjars, etc.).

Voici la note officielle, ce qui a changé dans le nouveau cadre de sécurité par rapport à ses anciennes versions:

Modifications de la sécurité dans Spring Boot 2.0 M4

J'espère que ça aidera quelqu'un. Je vous remercie! Bonne journée!

15
Thomas Lang

Si vous utilisez des webjars. Vous devez ajouter ceci dans votre méthode configure: http.authorizeRequests().antMatchers("/webjars/**").permitAll();

Assurez-vous que ceci est la première déclaration. Par exemple:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/webjars/**").permitAll();
        http.authorizeRequests().anyRequest().authenticated();
         http.formLogin()
         .loginPage("/login")
         .failureUrl("/login?error")
         .usernameParameter("email")
         .permitAll()
         .and()
         .logout()
         .logoutUrl("/logout")
         .deleteCookies("remember-me")
         .logoutSuccessUrl("/")
         .permitAll()
         .and()
         .rememberMe();
    }

Vous aurez également besoin de cela pour pouvoir activer les webjars:

@Configuration
    public class MvcConfig extends WebMvcConfigurerAdapter {
        ...
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        }
        ...
    }
8
ACV
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        String[] resources = new String[]{
                "/", "/home","/pictureCheckCode","/include/**",
                "/css/**","/icons/**","/images/**","/js/**","/layer/**"
        };

        http.authorizeRequests()
                .antMatchers(resources).permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout().logoutUrl("/404")
                .permitAll();
        super.configure(http);
    }
}
4
Huangxu Huang

j'ai eu le même problème avec mon application de démarrage de printemps, donc je pensais que ce serait bien si je partagerais avec vous ma solution. Je viens de configurer simplement le antMatchers pour qu’il soit adapté à un type spécifique de filles. Dans mon cas c'était seulement js filles et js.map. Voici un code:

   @Configuration
   @EnableWebSecurity
   public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests()
      .antMatchers("/index.html", "/", "/home", 
       "/login","/favicon.ico","/*.js","/*.js.map").permitAll()
      .anyRequest().authenticated().and().csrf().disable();
   }
  }

Ce qui est intéressant. Je découvre que chemin des ressources comme ( "ressources/myStyle.css" dans antMatcher n'a pas fonctionné pour moi du tout. Si vous avez un dossier dans votre dossier resoruces, ajoutez-le simplement dans antMatcher comme "/ myFolder/myFille.js" * et cela devrait fonctionner correctement.

1
Komoito