Spring Security

황상익·2024년 9월 2일

security

목록 보기
1/16

초기화 설정

자동 설정의 의한 기본 보안 작동

자동 설정의 의한 기본 보안 작동
서버가 가동되면 시큐리티의 초기화 및 보안 설정 가동
별도의 설정이나 코드 작성 없이 -> 기본적 웹 보안기능
1) 모든 요청에 대하여 인증 여부 검증
2) 인증 방식은 폼 로그인 방삭, HttpBasic 로그인 방식
3) 인증을 시도 할 수 있도록, 로그인 페이지, 자동 렌더링
4) 승인이 이뤄질 수 있도록 한개의 계정이 기본적 제공이 됨

  • SecurityProperites 설정 클래스에서 생성
  • username : user
  • Password : 랜덤 문자열
    -> 인증을 받지 못하면 어떤 요청에 대해서도 넘기지 않는다. (authenticated)
    인증을 받을 수 있도록 방법을 제공 (formLogin, httpBasic)
    => 하나의 계정은보안에 대해 제공을 하지만, 계정을 추가, 권한 등은 기본적 보안을 갖고는 해결하기 힘들다
Using generated security password: 4b524ee4-462f-47c5-abdf-58d67e04b71d 

-> random한 Password가 들어있다. (내부적으로 하나의 계정 제공됨)

SpringSecurityProperties은 하나의 계정을 제공하는 System이라고 본다. user계정이 하나 생성, Password -> UUID random

두 아이디의 정보가 맞으면 인증 성공

HttpSecurity Class 자체 주입
-> 인증 방식은 폼 로그인 방식, HttpBaisc 로그인 방식
인증을 시도 할 수 있도록, 로그인 페이지 & 자동 렌더링
승인이 이뤄질 수 있도록 한개의 계정 기본 제공

초기화 과정

SpringBootWebSecurityConfiguration에 있는 두 조건이 참이여야 진행이 된다.
1. 의존성에 존재하는지에 유무
2. SecurityFilterChain에 Bean이 존재 하는지 유무
존재 하지 않는다면, true / 존재한다면 false

SecurityBuilder & SecurityConfigurer

SpringSecurity → SecurityBuilder, SecurityConfigurer
SpringSecurity → 필터기반 보안 framework

1) SecurityBuilder
-> web 보안을 담당하는 Bean 객체 설정 클래스들의 생성하는 역할 (WebSecurity, HttpSecurity).
== Http 요청과 관련된 보안
2) SecurityConfigurer는 Http 요청과 보안처리를 담당하는 필터들을 생성하고 여러 초기화 설정에 관여
3) SecurityBuilder는 SecurityConfigurer를 참조 (인증 및 초기화)

과정을 글로 나태나자면
AutoConfig → 자동 설정 → SecurityBuilder를 생성 → Web보안을 구성하는 Bean들 생성 (init Builder, Configure Builder) → 초기화, filter 생성 = 인증, 인가

SecurityBuilder → HttpSecurity 생성 → 설정 클래스 생성 → init, Configure (초기화 작업 진행) → 각각의 Configure 마다

Security debug 해보면 무슨 말인지 이해 할 것이다.

WebSecurity / HttpSecurity

HttpSecurity => propertyBean 타입
설정 값들의 예시라고 보면 된다.

1) csrf → csrfConfigurer → SecurityConfigurer 어딘가에 적용 
2) exceptionHandling → exceptionHandlingConfigurer 처리 

여러 설정 처리 후 Bean 객체를 생성, Bean 객체를 받아서 초기화 진행이되고 -> SpringBootWebSecurity 진행

HttpConfigurer 작업을 처리 받아 설정을 이룬다. = build를 통해서 초기화 작업들이 처리된다.

HttpSecurity

HttpSecurityConfiguration에서 HttpSecurity를 생성, 초기화 진행
보안에 필요한 각 설정 클래스들과 필터들 생성 -> SecurityFilterChain Bean 생성 (진짜 목적)

즉 각 Configure 설정을 build 하면서 init과 Configure 인증과 인가 관련된 filter들 생성
SecurityFilterChain이라는 Bean 안에 생성. (여러 필터들 목록 생성)

최종적으로 생성된 Bean => SecurityFilterChain 생성 -> (requestMatcher + filter)

SecurityFilterChain

1) boolean matches (HttpServletRequest request)

처리 되어야 하는지 여부를 결정
true를 반환하면 현재 요청이 필터 체인 처리 -> false 반환하면 다른 필터 체인이난 처리 로직에 의해 처리

2) List<Filter> getFilters()

Filter 객체의 리스트를 반환
어떤 필터들이 현재 필터 체인에 포함되어 있는지 확인 가능, 각 필터는 요청 처리 과정에서 특정 작업을 수행

WebSecurity

WebSecurityConfiguration -> WebSecurity를 생성, 초기화
HttpSecurity에서 생성한 SecurityFilterChain빈을 SecurityBuilder에 저장
WebSecurity가 build를 실행 -> SecurityBuilder에서 SecurityFilterChain을 꺼내서 FilterChainProxy 생성자에게 전달

SecurityFilterChain을 꺼내서 저장 → SecurityFilterChains가 모든 설정에 다 갖고 있는 모습이 됨 (List) == 클라이언트 요청 준비 끝!

WebSecurityConfiguration는 HttpSecurity가 빈으로 참조 되어야 webSecurity를 생성할 수있다.
빈을 통해서 httpSecurity가 SecurityFilterChain을 최종적으로 완성
SecurityFilterChain -> filter 생성 완료

httpSecurity -> DefualtSecurityFilterChain을 생성 -> requestMachers, Filter 넘겨준다.
requestMachers: 현재 요청이 Security에 필요한가를 봄 (type - anyRequestMatchers = 모든 요청에도 검증)

과정을 글로 표현하자면
DefualtSecurityFilterChain → webSecurity에 저장 ) SecurityFilterChain을 활용 하기 위함 & 저장 → build → FilterChainProxy → securityFilterChain을 완성 → return (FilterChainProxy)가 최종적으로 생성이 된 것. = Filter type

Filter

서블릿 필터는 웹 애플리케이션에서 클라이언트의 요청과 응답을 가공 -> ServletRequest, ServletResponse
클라이언트 요청이 서블릿 도달하기 전 응답을 클라이언트에게 보내기 전 특정 작업 수행

Delegating Filter Process

스프링에서 제공하는 특별한 서블릿 필터, 서블릿 컨테이너와 스프링 애플리케이션 컨텍스트 간 연결고리
서블릿 필터의 기능을 수행하는 동시에 스프링 의존성 주입 및 빈 관리 기능과 연동되도록 설계
springSecurityFilterChain 이름으로 된 빈을 ApplicaitonContext에서 찾아서 요청

Was <> delegatingFilterProxy ←→ Spring IOC Container 

filter는 springContainer에서 생성되지 않음.
delegatingFilterProxy를 통해서 filter라는 타입을 bean으로 생성해서, SpringContainer가 갖고 있는 기능을 사용하기 위해 사용

가장 중요한 것은 delegatingFilterProxy가 찾는 Bean이 FilterChainProxy라는 것만 알고 있으면 된다.
springSecurityFilterChain의 이름으로 생성된 필터 빈으로서 delegatingFilterProxy 요청을 위임 받고 보안 처리
내부적으로 하나 이상의 SecurityFilterChain 객체즐을 소유 하고 있고, URL 기주으로 적절한 SecurityFilterChain을 선택 -> filter 호출

순서
delegatingFilterProxy → FilterChainProxy를 찾고 ( securityFilterChain이름으로 된 Bean을 찾음 ) → 요청을 그대로 위임 → securityFilterChain & 목록 filter 하나하나 처리하도록 처리 → MVC

사용자 정의 보안 기능 구현

SecurityFilterChain 타입의 빈을 정의한 후 API 및 인가 API 설정

securityFilterChain → requetsMatcher, filter 목록들 → web 보안 기능 동작 → 하나라도 설정 하지 않으면, 자동으로 Bean 생성 (@EnableWebSecurity) 설정

SecurityFilterChain → HttpSecurity 설정 (객체 필요) → 인증 API, 인가 API

@Configuration
@EnableCaching
public class SecurityConfig {

    //메모리 상에서 사용자 설정
    //설정 파일과 중복이 있다면, @Bean 인메모리 방식이 우선
    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {

        //User객체는 SpringSecurity가 갖고 있는 User
        UserDetails user = User.withUsername("user")
                .password("{noop}1111") //(noop)을 사용하면 평서문 처럼 사용 가능
                .authorities("USER")
                .build();

        return new InMemoryUserDetailsManager(user);
    }

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

        http
                //SecurityFilterChainConfiguration -> filter 조건 성립 안됨
                //SecurityFilterChain -> Bean을 생성했기 때문 -> Bean이 없을 경우에만 성립된다. -> 사용자가 설정한 쪽으로 오게 된다.
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                //인증을 받지 못했을 경우 인증을 받을 수 있게 설정
                .formLogin(Customizer.withDefaults());

        return http.build(); // securityFilterChain 생성된다.
    }
}
profile
개발자를 향해 가는 중입니다~! 항상 겸손

0개의 댓글