Spring Security - SecurityFilterChain ( HttpSecurity )

TopOfTheHead·2025년 11월 18일

Spring Security

목록 보기
18/27

SecurityFilterChain :
import org.springframework.security.web.SecurityFilterChain;

Spring Security에서 제공하는 보안 filter 모음 역할의 Interface.
( Authentication Filter , Authorization Filter , CORS Filter , CSRF Filter , ExceptionTranslation Filter 등)
@Configuration을 통해 Spring Bean으로 등록하여 필터를 설정

Web Security Configuration를 정의하는 @Configuration Class를 통해 Spring Bean으로 등록 시 Delegating Filter Proxy를 통해 Servlet Filter Chain 사이에서 Filter로서 의존성 주입되어 기능

Spring Security의 핵심이 되는 기능을 제공하여 사용자에게 적절한 AuthenticationAuthorization이 부여

SecurityFilterChain구현체로서 HttpSecurity가 존재
FilterChain을 통해 설정 후 HttpSecurity객체.build()로 생성된 HttpSecurity instance를 반환하여 SecurityFilterChain으로서 Spring Bean으로 등록
▶ 이후 @EnableWebSecurity에 의해 해당 Spring Bean이 활성화

Filter Chain의 경우 Filter에 따른 검증이 순차적으로 적용.
1. CORS , CSRF 등의 Filter :
。기본필터

2. Authentication Filter :
。적절한 자격증명 보유 여부 Filtering

3. Authorization Filter :
。접근하려는 자원에 적절한 접근권한이 있는지 Filtering

  • Security Filter Chain 핵심적인 기능
    。기본적으로 ControllerMapping된 모든 URL을 대상으로 보호를 수행
    ▶ 해당 URL에 대해 요청 시 사용자에게 인증정보를 요구

    。 승인되지 않은 요청에 대해서는 비허용
    URLHttp Request가 전송되었을때, SecurityFilterChain필터를 통해 사용자가 인증( Authenticate )되지 않은 경우, 만약 form-based login이 활성화 되었을때 Login Form을 표시

CSRF 관련 설정, CORS 관련 설정

HttpSecurity
특정 HTTP Request에 대한 웹보안Configuration을 설정하는 역할의 SecurityFilterChain 인터페이스 구현체
Default로서 모든 Http Request에 대해 적용

@Bean 메서드매개변수의존성주입되며, 해당 메서드에서 필터 설정을 수행한 이후 SpringFilterChain으로 반환함으로써 Spring Bean으로 등록
▶ 이후 해당 설정을 기반으로 요청 / 응답인증 / 인가를 수행

Resource(URL)의 접근 권한을 설정
▶ 특정 Resource접근 권한 또는 특정 권한을 가진 사용자접근 권한을 설정

Spring Security의 각종 Configuration을 수행.
@Configuration Class@Bean Method에서 HttpSecurity객체에서 Filter Chain을 구현 후 HttpSecurity객체.build()HttpSecurity객체를 생성 및 SecurityFilterChain객체로서 return하여 Spring Bean으로 등록함으로써 Spring Security의 설정을 반영.

Spring Security 6.x 부터는 메서드 체이닝이 아닌, 람다식기반 설정방식 권장

httpsecurity객체.authorizeHttpRequest(람다식) :
Spring Framework에 전달되는 HttpRequest에 대한 접근권한을 설정하는 Method.
HttpRequest을 특정 패턴에 따라서 filtering하고 접근권한을 부여

HttpSecurity객체에 대하여 input된 인증이 된 모든 HttpRequest에 대하여 승인처리 설정.
구현하지 않는 경우, 모든 HTTP Request에 대해서 거절

콜백함수매개변수auth를 전달하며, 해당 변수를 통해 어플리케이션API 호출에 따른 모든 HttpRequest에 대한 접근권한 설정이 가능.

  • 접근권한 설정 시 먼저 설정한 엔드포인트에 대한 접근권한이 우선적으로 적용된다.
.requestMatchers(HttpMethod.POST, "/api/v1/npcs/read").permitAll()
.requestMatchers(HttpMethod.POST, "/api/v1/npcs/**").authenticated()

▶ 다음처럼 설정 시 /api/v1/npcs/read 엔드포인트에 대해 모든 사용자가 접근 가능하고, 이하 나머지 엔드포인트인증된 사용자만 접근가능하도록 설정됨


HTTP Request접근권한 설정 Method ( Global Security )
HttpSecurity.authorizeHttpRequests(람다식)에서 람다식이 전달하는 인자( = auth)를 통해 설정.
▶ 구현하지 않는 경우, 모든 HTTP Request에 대해서 거절


인가검증할 대상 URL 패턴 지정
requestMatchers(), anyRequest()

  • auth.requestMatchers( HTTPMethod.메소드명 , "/URL Pattern1" , "/URL Pattern2", ...)
    HTTP Request의 특정 URL patternHTTP Method에 대해서 접근 권한을 설정 시 사용하는 메서드
    ▶ 나머지 HTTP Request에 대해서는 auth.anyRequest()에서 정의

    URL Pattern을 정의한 String[] 인자도 받을 수 있다.

    。기존 antMatchers()처럼 URL 전체를 모두 일치해야 허용하는 방식에서 URL Pattern일치해야 허용하는 방식으로 개선

    ex) auth.requestMatchers(HttpMethod.OPTIONS, "/login/**").permitAll() :
    /login 이후의 URL PatternOPTIONS HTTP Method방식의 HTTP Request는 모두 허용.


    auth.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
    CORS 관련 설정으로서, Preflight Request이 전달되어 인가 검증을 수행하는 경우 모두 허용하도록 설정

  • auth.anyRequest() :
    。따로 접근권한을 설정한 특정 HTTP Request 이외의 모든 HTTP Request에 대한 접근권한을 정의하는 메서드
    .anyRequest().requestMatchers("/**")처럼 동작
http.authorizeHttpRequests(
                auth->auth.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                        .anyRequest().authenticated()
        )

auth.requestMatchers에서 정의한 HTTP Request 이외의 모든 HTTP Request에 대해 인증된 사용자만 접근가능하도록 설정.


인가 검증 메서드
requestMatchers(), anyRequest()를 통해 설정된 대상을 검증 수행

  • auth.anonymous()
    인증이 되지 않은 익명 사용자만 접속할 수 있도록 설정하는 인가 검사 메서드
    인증된 사람은 차단

    。보통 로그인 페이지에서 작성 ( 로그인 한 사람이 또 로그인 하면 안되므로 )
http.authorizeHttpRequests(auth -> auth
            .requestMatchers("/login/**").anonymous()
       )

/login/**URL Pattern을 가진 요청인증되지 않은 사용자만 접근 가능.

  • auth.hasRole("역할명")
    。해당 URL 패턴에 특정 Role을 가진 사용자만 접근할 수 있도록 제한하는 인가 검사 메서드
    역할명만 입력 시 GrantedAuthority 내부의 ROLE_역할명과 자동으로 매칭
http.authorizeHttpRequests(auth -> auth
            .requestMatchers("/admin/**").hasRole("ADMIN")
               )

/admin/**URL Pattern을 가진 요청"ROLE_ADMIN"을 가진 사용자만 접근 가능.

  • auth.hasAnyRole("역할명1", "역할명2", ... )
    。해당 URL 패턴에 정의된 여러 개의 Role 중 해당하는 역할을 가진 사용자만 접근 할 수 있도록 제한하는 인가 검사 메서드

  • auth.hasAuthority("ROLE_역할명")
    。해당 URL 패턴에 특정 Role을 가진 사용자만 접근할 수 있도록 제한하는 hasRole()과 동일 역할의 인가 검사 메서드
    hasRole()과 달리 "ROLE_역할명"을 모두 입력하여 GrantedAuthority 내부의 ROLE_역할명매칭

  • auth.hasAnyAuthority("ROLE_역할명1", "ROLE_역할명2", ...)
    。해당 URL 패턴에 정의된 여러 개의 Role 중 해당하는 역할을 가진 사용자만 접근 할 수 있도록 제한하는 hasAnyRole()과 동일한 역할의 인가 검사 메서드
    "ROLE_역할명"을 모두 입력

  • auth.authenticated()
    。해당 URL 패턴에 대해 AuthenticatedClient만 접근가능하도록 설정하는 인가 검사 메서드
    auth.anonymous() 와 반대

  • auth.permitAll()
    。해당 URL 패턴에 대해 인증되거나, 되지 않거나 상관없이 모든 HTTP Request에 대해 허용.
    ▶ 따로 접근권한을 설정한 특정 HTTP Request가 없는 경우 보안 없이 개방하는것과 같음.

  • auth.denyAll()
    。해당 URL 패턴에 대해 모든 HTTP Request에 대해 차단하는 인가검사 메서드

    。주로 인가검증 메서드 설정에서 마지막에 설정하여, 위에서 정의한 접근 가능한 URL외 모든 URL에 접근 시 차단하여 내부 자원을 보호
auth
  .requestMatchers("/sign-up")
  .permitAll()
  .requestMatchers("/login-page")
  .anonymous()
  .requestMatchers("/user/**")
  .hasAuthority("USER")
  .anyRequest()
  .denyAll();

/sign-up, /login-page, /user/**URL로 접근하는 모든 요청을 차단

HttpSecurity객체.httpBasic(Customizer.withDefaults())
。Spring Security에서 HTTP Basic Authentication을 활성화하는 Method.
▶ Clent의 ID와 PW를 HTTP RequestAuthorization Header에 포함하여 인증하는 방식.

Authorization Header 요구 시 Basic Authentication 도출.
Basic Authentication : 웹브라우저의 인증 팝업으로 Authorization HeaderID/PW 입력 기능 제공.

HTTP Basic : Header에 ID와 PW를 포함 및 Base64로 인코딩하여 HTTP Authorization Header에 포함하여 Server로 전송.

HttpSecurity객체.headers(콜백함수)
HttpRequest에 대한 Http Response Header를 설정하는 method.
Spring Security는 보안 관련 HTTP Header를 자동으로 추가하지만,
필요에 따라 추가하거나 비활성화 설정 가능.

람다식의 매개변수로서 Http header객체가 전달

http.headers(header -> header.frameOptions(frameOptions->frameOptions.disable()));
  • header객체.frameOptions(람다식) :
    HTTP Header을 통해 Web Applicationiframe 보안정책을 설정하는 기능.
    ▶ 주로 Clickjacking 공격을 방지하는 역할을 수행.

    frameOption객체람다식 인자로 전달됨

    <iframe> : inline frame
    。HTML에서 다른 웹페이지나 문서를 현재 페이지 내에 삽입할 때 사용하는 태그.
    ▶ 외부 웹사이트, 동영상, 지도, 문서등을 포함 가능
    • frameoption객체.disable() :
      Http HeaderFrameOption을 비활성화.
      ▶ 모든 iframe을 허용하여 iframe 기반 UI ( ex. h2-console )을 사용 시 필요하지만 보안위험이 존재하므로, 신뢰할 수 있는 경우에만 사용.

    • frameoption객체.sameOrigin() :
      iframe을 같은 도메인에서 오는 `HTTP Request에 대해서만 허용.
      ▶ 동일한 도메인에서만 iframe을 사용가능하고, 다른 도메인에서는 차단.

HttpSecurity객체.build() :
Configuration이 수행된 HttpSecurity객체를 생성.
▶ 주로 SecurityFilterChain InterfaceUpCasting하여 Spring Bean으로 등록

HttpSecurity객체.sessionManagement(콜백함수) :
Spring Security에서 세션 관리 전략을 설정하는 Method.

Session을 사용하지 않는 Stateless 방식의 JWT 기반 인증REST API 규약을 위해 Session Policy에서 STATELESS 설정 시 활용
Spring Security는 기본적으로 Session을 사용하므로 Session이 생성되지 않도록 설정

Session이 없는 경우 추가로 CSRF Protection을 비활성화 가능

Form Based LoginSession을 사용하는 인증방식의 경우 사용하도록 설정해야한다.

。매개변수로 session이 전달되며, 람다식으로 session.sessionCreationPolicy(Session Policy 설정 옵션)를 통해 Spring Security가 설정한 Session Policy에 따라 Session의 처분을 결정.

httpsecurity객체.sessionManagement(
    session->session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
 )

Spring SecuritySession을 사용하지 않도록 Session Policy 설정.

Session Policy 설정 옵션
import org.springframework.security.config.http.SessionCreationPolicy;

  • SessionCreationPolicy.ALWAYS :
    。항상 새로운 Session을 생성하도록 Session Policy 설정.

  • SessionCreationPolicy.NEVER :
    Spring SecuritySession을 생성하지 않지만, 기존 Session을 사용가능하도록 Session Policy 설정.

  • SessionCreationPolicy.IF_REQUIRED :
    。기본값으로서, 필요한 경우에만 Session을 생성하도록 Session Policy 설정.

  • SessionCreationPolicy.STATELESS :
    Session을 사용하지 않도록 Session Policy 설정.
    JSESSIONID 쿠키는 생성되지만, 세션 자체가 생성 되지 않고 인메모리 DB에 저장되지도 않음.

    주로 JWT Token을 활용하는 REST API Authentication 구현 시 사용.

HTTPSecurity객체.oauth2Login(Customizer.withDefaults())
Spring Security에서 Oauth 2.0 로그인 기능을 활성화하는 메서드
▶ 다음 설정을 끝낸 후 localhost:8080/login 접속 시 해당 API보호하기위해 application.yml에 등록된 OAuth2 Provider ( ex. Google 등 )에 의해 로그인옵션이 자동으로 표시됨.

localhost:8080/logout 접속 시 로그아웃을 수행.



  • oauth2.successHandler(AuthenticationSuccessHandler)
    Spring Security에서 OAuth2 로그인 성공 이후 실행 동작을 직접 정의하여 등록하는 Handler
    ▶ 주로 로그인 성공 이후 OAuth를 통한 JWT 발급을 수행하는 이벤트 핸들러를 정의 후 등록.
.oauth2Login(oauth2->{
                    oauth2.successHandler(oauth2SuccessHandler);
                })

Security Filter Chain 구성

Filter를 넣어야하는 위치는 다음 도식을 통해 결정

JWT 기반 로그인 검증을 수행하는 경우 Security Filter ChainUsernamePasswordAuthenticationFilter 직전에 JWT 토큰검사 필터를 삽입

로그인 이후 SecurityContextHolderAuthentication 구현체에 등록 시 UsernamePasswordAuthenticationFilterDefaultLoginPageFeneratingFilterSkip하도록 설정

Authentication 구현체가 등록되지 않은 경우 UsernamePasswordAuthenticationFilterDefaultLoginPageFeneratingFilter가 동작하여 로그인 페이지 도출

  • UsernamePasswordAuthenticationFilter
    사용자ID / PW 로그인 요청을 전송 시 인증을 수행하는 필터

  • DefaultLoginPageFeneratingFilter
    기본 로그인 페이지를 자동생성하는 필터
    form Based LoginSpring Login 페이지를 자동 생성

Filter Chain사용자 정의 필터 구현체 등록하기
OncePerRequestFilter 상속 클래스Security Filter ChainFilter로서 등록하기

。주로 로그인JWT 검증 필터, OAuth에서 JWT 검증 필터 등을 추가할 때 활용

  • httpSecurity객체.addFilter(필터객체)
    Security Filter Chain 내 마지막에 필터 등록

  • httpSecurity객체.addFilterAt(필터객체)
    Security Filter Chain 내 마지막에 필터 등록

  • httpSecurity객체.addFilterBefore(필터객체, 필터체인 내 특정필터.class)
    Security Filter Chain특정 필터 기준 직전에 필터를 등록
    ex ) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)

    。주로 UsernamePasswordAuthenticationFilter 직전JWT 검증 필터 등록하여 로그인 성공 시 해당 필터Skip하도록 설정.
    로그인 실패UsernamePasswordAuthenticationFilter가 작동

  • httpSecurity객체.addFilterAfter(필터객체, 필터체인 내 특정필터.class)
    Security Filter Chain특정 필터 기준 직후에 필터를 등록
    ex ) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
profile
공부기록 블로그

0개의 댓글