codememo

Spring Boot & Spring Security 응용 프로그램에서 정적 웹 리소스 제공

tipmemo 2023. 3. 9. 22:05
반응형

Spring Boot & Spring Security 응용 프로그램에서 정적 웹 리소스 제공

Spring Boot 웹 어플리케이션을 개발하고 Spring 보안 Java 설정을 사용하여 보안 보호하려고 합니다.

Spring 블로그의 조언에 따라 정적 웹 리소스를 'src/main/resources/public'에 배치하면 정적 리소스를 얻을 수 있습니다.즉, 브라우저에서 누르면 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
    }

src/main/resources/public 내부에 배치된 정적 리소스를 허용하도록 antMatchers를 설정하려면 어떻게 해야 합니까?

주의할 점이 몇 가지 있습니다.

  • Ant matchers는 파일 시스템의 리소스 경로가 아닌 요청 경로와 일치합니다.
  • 「」에 src/main/resources/public는 어플리케이션의 루트에서 제공됩니다.를 들어, 「」입니다.src/main/resources/public/hello.jpg로부터 제공되다http://localhost:8080/hello.jpg

따라서 현재 매처 구성에서 정적 리소스에 대한 액세스를 허용하지 않습니다.★★★의 /resources/**일일하하 the, the을배 to to to to to to to에 배치해야 합니다.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 and and 、 음 、 음 、 음 、 음음음음 and and and and and and 。http://localhost:8080/images/hello.jpg로그인하지 않아도 됩니다.이는 특별한 설정 없이 부트스트랩 CSS 파일에 대한 액세스가 허용되는 웹 메서드보안 스모크테스트에서 확인할 수 있습니다.

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

"/resources/"로 시작하는 모든 요청을 무시하십시오.이는 XML 네임스페이스 설정을 사용할 때 http@security=none을 설정하는 것과 비슷합니다.

이는 답변(스프링 부트 2)과 동시에 질문일 수 있습니다.스프링 부트2와 스프링보안 조합에서는 모든 것(모든 루트/앤트매처)이 디폴트로 보호되고 있는 것처럼 보입니다.이것은, 다음의 각 시큐러티 메카니즘을 사용하고 있는 경우입니다.

WebSecurityConfigurerAdapter

개별 보안 메커니즘을 사용하지 않으면 모든 것이 그대로입니까?

Andy Wilkinson이 위의 답변에서 말한 것처럼 오래된 스프링 부트 버전(1.5 이하)은 다음과 같습니다.public/** or static/**는 기본적으로 허용됩니다.

이 질문/답변으로 요약하자면 스프링부트 2를 스프링보안과 함께 사용하고 있으며 개별 보안 메커니즘을 가지고 있는 경우 모든 루트에 배치된 정적 콘텐츠에 대한 접근을 배타적으로 허용해야 합니다.다음과 같은 경우:

@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 이하를 사용하고 있는 경우는, 이러한 장소(스태틱/퍼블릭/Webjar 등)를 명시적으로 허가할 필요는 없습니다.

다음은 새로운 보안 프레임워크에서 이전 버전과 관련하여 변경된 사항입니다.

Spring Boot 2.0 M4 보안 변경

이게 도움이 됐으면 좋겠어요.감사해요!좋은 하루 보내세요!

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

스텝 2. 추가configure(WebSecurity web)SecurityConfig 클래스로 덮어쓰기

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

스텝 3. 모든 정적 리소스를 webapp/리소스/..에 배치합니다.

웹자어를 사용하는 경우.이 항목을 에 추가해야 합니다.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();
    }

Webjar 를 유효하게 하려면 , 다음의 기능도 필요합니다.

@Configuration
    public class MvcConfig extends WebMvcConfigurerAdapter {
        ...
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        }
        ...
    }
@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);
    }
}

스프링 부츠 앱에서도 같은 문제가 있었기 때문에 솔루션을 공유하면 좋을 것 같습니다.특정 유형의 필에 적합하도록 antMatchers를 구성하기만 하면 됩니다.내 경우 js filles와 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/myStyle.css"와 같은 리소스 경로가 전혀 작동하지 않았음을 알게 되었습니다.Resources 폴더에 폴더가 있는 경우 "/myFolder/myFille.js"*와 같이 antMatcher에 폴더를 추가하면 정상적으로 작동합니다.

최신 Spring Security 6에서는WebSecurityConfigurerAdapter는 권장되지 않습니다.

선언하다WebSecurityCustomizer대신 콩을 주세요.

 @Bean
 public WebSecurityCustomizer ignoringCustomizer() {
     return (web) -> web.ignoring().requestMatchers("...");
 }

스프링 보안 6.0에 적용됩니다.*

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {


        http
                .csrf()
                .disable()
                .authorizeHttpRequests()
                .requestMatchers(
                        "/home/**",
                        "/login/**",
                        "/account/starter/**",
                        "/register/**",
                        "/plugins/**",
                        "/dist/**",
                        "/js/**",
                        "/**/favicon.ico").permitAll()
                .and()
                .httpBasic()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        return http.build();
    }

 
                        "/plugins/**",
                        "/dist/**",
                        "/js/**",

...리소스에 배치되어 있습니다.

plugins, dist, js - 리소스가 있는 디렉토리의 이름입니다.

언급URL : https://stackoverflow.com/questions/24916894/serving-static-web-resources-in-spring-boot-spring-security-application

반응형