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

Kum*_*hav 62 spring-mvc spring-security spring-boot

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

按照Spring博客中的建议将静态Web资源放入' src/main/resources/public '后,我就能获得静态资源.即在浏览器中点击确实提供html内容.https://localhost/test.html

问题

启用S​​pring 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
    }
Run Code Online (Sandbox Code Playgroud)

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

And*_*son 90

有几点需要注意:

  • 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时,您可能需要考虑使用其默认值而不是添加额外配置.春天开机后,默认,允许访问/css/**,/js/**,/images/**,和/**/favicon.ico.例如,您可以拥有一个名为的文件src/main/resources/public/images/hello.jpg,在不添加任何额外配置的情况下,http://localhost:8080/images/hello.jpg无需登录即可访问.您可以在Web方法安全示例中看到此操作,其中允许访问Bootstrap CSS文件没有任何特殊配置.

  • 如果您使用的是 Spring Boot 2,请参阅 Thomas Lang 的回答 (4认同)

小智 29

  @Override
      public void configure(WebSecurity web) throws Exception {
        web
          .ignoring()
             .antMatchers("/resources/**"); // #3
      }
Run Code Online (Sandbox Code Playgroud)

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

  • 对我来说也不起作用。当我从 API 加载静态 html 时,并参考 /resources/css/main.css 中的静态文件之一。Rest API 渲染的 html 页面工作正常。然而,静态CSS则不然。 (2认同)

Jas*_*erJ 20

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

步骤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/");
    }
}
Run Code Online (Sandbox Code Playgroud)

步骤2.configure(WebSecurity web)向您的SecurityConfig类添加覆盖

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

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

  • 你能解释一下你在做什么以及为什么吗?“Step1”:添加静态资源处理。“Step2”:移除静态资源处理。 (2认同)
  • 如果有人使用 XML 配置,那么在**步骤 1** 中,您可以在 `dispatcher-servlet.xml 中使用此行 `<mvc:resources mapping="/resources/**" location="/resources/" />` ` 而不是创建新的 Java 配置类。 (2认同)

Tho*_*ang 17

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

WebSecurityConfigurerAdapter
Run Code Online (Sandbox Code Playgroud)

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

在较旧的春季靴子版本(1.5及以下)中,Andy Wilkinson在上面的回答中表示public/** or static/**默认允许的地方.

所以总结一下这个问题/答案 - 如果你使用具有弹簧安全性的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());
}
Run Code Online (Sandbox Code Playgroud)

}

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

.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
Run Code Online (Sandbox Code Playgroud)

如果您使用1.5及更低版本的spring boot,则不需要明确允许这些位置(静态/公共/ webjars等).

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

Spring Boot 2.0 M4中的安全性更改

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

  • 我可以确认添加额外的行为我修复了它(Spring Boot 2.0.3) (2认同)
  • 额外的行确实有很大帮助,但我需要添加更多行才能使其正常工作。启动版本2.0.6。(1) .antMatchers("/", "/callback", "/login**", "/webjars/**", "/error**", "/static/**").permitAll() 和(2)registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); 在 WebMvcConfigurer.addResourceHandlers() 下。 (2认同)

ACV*_*ACV 8

如果您使用的是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();
    }
Run Code Online (Sandbox Code Playgroud)

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

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


小智 6

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)