首页 文章

在Spring Boot和Spring Security应用程序中提供静态Web资源

提问于
浏览
54

我正在尝试使用Spring安全性Java配置开发Spring Boot Web应用程序并保护它 .

按照here in Spring blog建议将静态Web资源放入' src/main/resources/public '后,我可以获取静态资源 . 即在浏览器中点击 https://localhost/test.html 会提供html内容 .

问题

启用Spring Security后,点击静态资源URL需要进行身份验证 .

我相关的Spring Security Java配置如下所示: -

@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
    }

我应该如何配置 antMatchers 以允许放置在src / main / resources / public中的静态资源?

7 回答

  • 84

    如果您使用的是webjars . 您需要在 configure 方法中添加此项: http.authorizeRequests().antMatchers("/webjars/**").permitAll();

    确保这是第一个声明 . 例如:

    @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();
        }
    

    您还需要启用此功能才能启用webjars:

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

    有几点需要注意:

    • Ant匹配器匹配请求路径,而不是文件系统上资源的路径 .

    • src/main/resources/public 中的资源将从您的应用程序的根目录提供 . 例如, src/main/resources/public/hello.jpg 将从 http://localhost:8080/hello.jpg 提供

    这就是您当前的匹配器配置不允许访问静态资源的原因 . 要使 /resources/** 正常工作,您必须将资源放在 src/main/resources/public/resources 中并在 http://localhost:8080/resources/your-resource 处访问它们 .

    当您使用Spring Boot时,您可能需要考虑使用其默认值而不是添加额外配置 . 默认情况下,Spring Boot将允许访问 /css/**/js/**/images/**/**/favicon.ico . 例如,您可以拥有一个名为 src/main/resources/public/images/hello.jpg 的文件,并且无需添加任何额外配置,无需登录即可在 http://localhost:8080/images/hello.jpg 访问 . 您可以在web method security sample中查看此操作,其中允许访问Bootstrap CSS文件任何特殊配置 .

  • 26
    @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
    @Override
          public void configure(WebSecurity web) throws Exception {
            web
              .ignoring()
                 .antMatchers("/resources/**"); // #3
          }
    

    忽略以“/ resources /”开头的任何请求 . 这与使用XML命名空间配置时配置http @ security = none类似 .

  • 1

    这可能是一个答案(对于 Spring 季启动2)和一个问题同时 . 似乎在spring boot 2中结合了spring security,默认情况下保护所有东西(意味着每个路由/ antmatcher),如果你使用从

    WebSecurityConfigurerAdapter
    

    如果你不使用个人安全机制,一切都是这样的?

    在较早的 Spring 季启动版本(1.5及以下版本)中,Andy Wilkinson在上述答案中声明默认允许使用 public/** or static/** 这样的地方 .

    所以总结这个问题/答案 - 如果你使用具有 spring 安全性的spring boot 2并且有一个单独的安全机制,你必须exclusivley允许访问放置在任何路由上的静态内容 . 像这样:

    @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());
    }
    

    }

    请注意这行代码,这是新的:

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

    如果你使用1.5及以下的 Spring 季启动,你不需要明确允许这些位置(静态/公共/ webjars等) .

    以下是官方说明,新安全框架中的旧版本本身发生了哪些变化:

    Security changes in Spring Boot 2.0 M4

    我希望这可以帮助别人 . 谢谢!祝你今天愉快!

  • 6

    经过20个小时的研究,这是最终的解决方案 .

    Step 1. 将'MvcConfig.java'添加到您的项目中 .

    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/");
        }
    }
    

    Step 2.configure(WebSecurity web) 覆盖添加到SecurityConfig类

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

    Step 3. 将所有静态资源放在webapp / resources / ..

  • 8

    我的 Spring 季启动应用程序遇到了同样的问题,所以我认为如果我能与你们分享我的解决方案会很好 . 我只是简单地将 antMatchers 配置为适合特定类型的filles . 在我的情况下,只有 js filles and js.map . 这是一个代码:

    @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();
       }
      }
    

    有趣的是什么 . 我发现antMatcher中的 resources path"resources/myStyle.css" 根本不适合我 . 如果你的resoruces文件夹中有文件夹,只需将它添加到antMatcher中,如 "/myFolder/myFille.js"* ,它应该可以正常工作 .

相关问题