ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring-Security] Default Security Configurations
    legacy/Spring Security 2024. 4. 25. 17:47

    Default Security Filter Chain

    기본적으로 Spring Security 프레임워크는 웹 애플리케이션 내부에 존재하는 모든 경로를 보호한다. 이러한 동작을 하는 이유는 기본적으로 설정된 filter chain 내부의 코드 때문이다.

     

    전체 코드
    package org.springframework.boot.autoconfigure.security.servlet;
    
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
    import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    import org.springframework.security.config.Customizer;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
    import org.springframework.security.web.SecurityFilterChain;
    
    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnWebApplication(
        type = Type.SERVLET
    )
    class SpringBootWebSecurityConfiguration {
        SpringBootWebSecurityConfiguration() {
        }
    
        @Configuration(
            proxyBeanMethods = false
        )
        @ConditionalOnMissingBean(
            name = {"springSecurityFilterChain"}
        )
        @ConditionalOnClass({EnableWebSecurity.class})
        @EnableWebSecurity
        static class WebSecurityEnablerConfiguration {
            WebSecurityEnablerConfiguration() {
            }
        }
    
        @Configuration(
            proxyBeanMethods = false
        )
        @ConditionalOnDefaultWebSecurity
        static class SecurityFilterChainConfiguration {
            SecurityFilterChainConfiguration() {
            }
    
            @Bean
            @Order(2147483642)
            SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
                http.authorizeHttpRequests((requests) -> {
                    ((AuthorizeHttpRequestsConfigurer.AuthorizedUrl)requests.anyRequest()).authenticated();
                });
                http.formLogin(Customizer.withDefaults());
                http.httpBasic(Customizer.withDefaults());
                return (SecurityFilterChain)http.build();
            }
        }
    }
    
    

    request.anyRequest().authenticated() 로 인해서 모든 요청에 대해서 인증 정보를 요구하게 된다.

    deafult filter chain

    모든 요청에 대해서 정말로 인증 정보를 요구하는지 확인해보겠다. 두 개의 API가 있는데, Account는 계좌 정보이고 Notices는 공지사항이다. 

    @RestController
    public class AccountController {
    
        @GetMapping("/myAccount")
        public String getAccountDetails() {
            return "Here are the account details from the DB";
        }
    }
    
    @RestController
    public class NoticesController {
    
        @GetMapping("/notices")
        public String getNotices() {
            return "Here are the notices details from the DB";
        }
    }

     

    /myAccount, /notices API를 요청하게 되면 아래 인증 정보를 요구하는 페이지로 이동된다.

    인증 페이지

     

    Custom Security Filter Chain

    기본 값을 사용하는 것이 아닌, 직접 정의한 filter chain을 사용할 수 있다. 

    일부 요청만 인증 정보 요구

    계좌 정보는 인증 정보를 요구하고, 공지사항은 인증을 요구하지 않도록 filter chain을 생성할 수 있다.

    • /myAccount : 인증 정보가 유효하면 요청 가능
    • /notices : 인증 정보 없이도 요청가능
    @Configuration
    public class ProjectSecurityConfig {
    
        @Bean
        SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
    
            /**
             * authenticated() : 인증 필요
             * permitAll() : 인증 필요 없음
             */
            http.authorizeHttpRequests((requests) -> {
                    requests.requestMatchers("/myAccount", "/myBalance", "/myLoans", "/myCards").authenticated()
                        .requestMatchers("/notices", "/contact").permitAll();
                }).formLogin(Customizer.withDefaults())
                .httpBasic(Customizer.withDefaults());
            return http.build();
    }

    모든 요청을 거부

    인증 정보를 정상적으로 입력하더라도 요청이 거부된다.

    @Configuration
    public class ProjectSecurityConfig {
    
        @Bean
        SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
    
            /**
             * denyAll() : 인증이 성공하더라도 요청이 거부된다. -> 403 Error
             */
            http.authorizeHttpRequests((requests) -> {
                requests.anyRequest().denyAll();
                }).formLogin(Customizer.withDefaults())
                .httpBasic(Customizer.withDefaults());
            return http.build();
    }

    모든 요청을 허용

    인증 정보를 요구하지 않고 모든 요청을 허용한다.

    @Configuration
    public class ProjectSecurityConfig {
    
        @Bean
        SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
    
            /**
             * permitAll() : 모든 요청을 허락한다.
             */
           http.authorizeHttpRequests((requests) -> {
                    requests.anyRequest().permitAll();
                }).formLogin(Customizer.withDefaults())
                .httpBasic(Customizer.withDefaults());
            return http.build();
        }
    }

     

Designed by Tistory.