Spring Security - 정수원 4일차

14. 사이트 간 요청 위조 - CSRF, CsrfFilter

  • 모든 요청에 랜덤하게 생선된 토큰을 HTTP파라미터로 요구

  • 요청 시 전달되는 토큰 값과 서버에 저장되는 실제 값과 비교한 후 만약 일치하지 않으면 요청은 실패한다.

  • Client

    • <input type=”hidden” name=”${_csrf.parameterName}” value=”${_csrf.token}” />
    • HTTP 메소드 : PATCH, POST, PUT, DELETE
  • Spring Security

    • http.csrf() : 기본 활성화 되어있음
    • http.csrf().dsabled() : 비활성화

1. DelegatingFilterProxy, FilterChainProxy

  1. 서블릿 필터는 스프링에 정의된 빈을 주입해서 사용 불가
  2. 특정한 이름을 가진 스프링 빈을 찾아 그 빈에게 요청을 위임
    • springSecurityFilterChain 이름으로 생성된 빈을 ApplicationContext에서 찾아 요청을 위임
    • 실제 보안처리를 하지 않음

FilterChainProxy

  1. springSecurityFilterChain의 이름으로 생성되는 필터빈
  2. DelegatingFilterProxy으로 부터 실제 요청을 위임받고 실제 보안 처리
  3. 스프링 시큐리티 초기화 시 생성되는 필터들을 관리하고 제어
    • 스프링 시큐리티가 기본적으로 생성하는 필터
    • 설정 클래스에서 API추가 시 생성되는 필터
  4. 사용자의 요청을 필터의 순서대로 호출하고 전달
  5. 사용자정의 필터를 생성해서 기존의 필터 전.후로 추가 가능
    • 필터의 순서를 잘 정의해야된다
  6. 마지막 필터까지 인증 및 인가 예외가 발생하지 않으면 보안 통과

  1. DelegatingFilterProxy가 처음으로 요청을 받는다
  2. springSecurityFilterChain 이 이름으로 가진 필터를 가져옴 == FilterChainProxy
  3. 그 후 FilterChainProxy에 invoke 해서 요청을 위임
  4. FilterChainProxy 가 이제 보안 처리를 해야되기 떄문에 getFilter해서 등록되어 있는 Filter들을 list로 가져온다
  5. list들을 VirtualFilterChain인 가상 필터체인한테 전달한다. 그리고 순서대로 보안 처리해준다
  6. 처리완료후 서블릿이나 springMVC로 간다

2. 필터 초기화와 다중 보안 설정

  • 설정 클래스 별로 보안 기능이 각각 작동
  • 설정 클래스 별로 RequestMatcher 설정
    • http.antMatcher(”/admin/**”)
  • 설정 클래스 별로 필터가 생성
  • FilterChainProxy가 각 필터들을 가지고 있음 ( 밑에 2번째 과정 )
  • 요청에 따라 RequestMatcher와 매칭되는 필터가 작동함
@Configuration
@EnableWebSecurity
@Order(0) //두개 이상의 설정이면 항상 순서를 정해줘야 된다.
public class SecurityConfig_02_02 extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .antMatcher("/admin/**")
                .authorizeRequests()
                .anyRequest().authenticated()
        .and()
                .httpBasic();

    }
}

@Configuration
@Order(1) // 만약 순서를 바꾸면 안된다. 넓은 범위를 뒤에 놔야됨, 좁은범위가 넓은범위에 십힘
class SecurityConfig_02_02_2 extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().permitAll() // 어떤 요청이든 허용
                .and()
                .formLogin();
    }
}
  1. WebSecurity에 들어가서 FilterChainProxy를 생성하면서 securityFilterChains 라는 객체를 전달해준다
  2. 이 객체는 두개의 설정 정보가 들어가있는데, 경로 설정한 requestMatcher라는 변수에 각각(”/admin/**")any request가 들어가있고 각각 filter가 들어가 있다. 전자는 httpBasic이라12개후자는 formLogin이라 password와 디폴트 경로설정등 합쳐서 14개가 들어가 있다.
  3. 그 후 루트 URL로 들어가면 가장 먼저 만나는게 FilterChainProxy인데 이떄 getFilters를 하게 된다. 이때 생성자로부터 받은 filterchains가 두개의 필터를 가지고있다. 그걸 getFilters에게 넘겨주고 이것이 요청에따라 매칭이 되는 것을 판별하여 돌려준다.

3. 인증 개념 이해 - Authentication

당신이 누구인지 증명하는 것

  • 사용자의 인증 정보를 저장하는 토큰의 개념
  • 인증 시 id 와 password를 담고 인증 검증을 위해 전달되어사용된다.
  • 인증 후 최종 인증 결과(user객체, 권한 정보)를 담고 SecurityContext에 저장되어 전역적으로 참조가 가능하다
    • Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
  • 구조
    • princial : 사용자 아이디 혹은 User 객체 저장
    • credentials : 사용자 비밀번호
    • authorities : 인증된 사용자의 권한 목록
    • details : 인증 부가 정보
    • Authenticated : 인증 여부

  1. 로그인을 한다
  2. 인증을 먼저 처리할 수 있는 AbstractAuthenticationProcessingFilter 에 간다(부모격인 인증필터) 그리고나서
  3. UsernamePasswordAuthentication에 드간다. id와 password로 토큰을 만들어서 AuthenticationManager에다가 저장한다
  4. ProviderManager로 간다 여기서 성공하면 성공 클래스로 간다음
  5. 마지막에 AbstractAuthenticationProcessingFilter에서 SecurityContextHolder.getContext().setAuthentication(authResult)

좋은 웹페이지 즐겨찾기