Spring Security

akanana·2023년 2월 2일
0

Spring-Security

목록 보기
1/8

일반적인 공격에 대한 인증/권한부여 및 보호기능을 위한 프레임워크

reading username/password

usernamepassword를 읽기위한 프레임워크

Form Login

로그인 동작은 다음과 같이 동작한다

인증되지 않은 상태에서 접근


1. 유저가 리소스(/private)에 non-auth한 요청을 전송
2. Spring SecurityFilterSecurityInterceptorAccessDeniedException를 리턴 및 거부
3. non-auth한 요청이므로, ExceptionTranslationFilterStartAuthentication을 시작, 설정된 AuthenticationEntryPoint를 로그인 페이지와 함께 redirect
4. 브라우저가 로그인페이지를 요청
5. 로그인 페이지를 렌더링

username/password를 제출
  1. username과 password를 제출시, UsernamePasswordAuthenticationFilterUsernamePasswordAuthenticationToken를 생성한다
    UsernamePasswordAuthenticationToken의 타입은 Authentication이다
    이때 username과 password는 HttpServletRequest에서 추출한 정보이다
  2. UsernamePasswordAuthenticationTokenAuthenticationManager로 전달되어 인증을 위임한다
  3. 실패!
    • SecurityContextHolder가 비워짐
    • RememberMeServices.loginFail이 호출
    • AuthenticationFailureHandler이 호출
  4. 성공!
    • SessionAuthenticationStrategy에 새로운 로그인 등록
    • SecurityContextPersistenceFilterSecurityContextHolder에 등록
    • RememberMeServices.loginSuccess이 호출
    • ApplicationEventPublisherInteractiveAuthenticationSuccessEvent를 등록
    • AuthenticationSuccessHandler이 호출
      기본적으로 이것은 SimpleUrlAuthenticationSuccessHandler이며, 로그인시 ExceptionTranslationFilter에 저장된 페이지로 리다이렉트
로그인 페이지

기본 로그인 페이지로 가기위해서 다음 코드를 사용 가능하다

public SecurityFilterChain filterChain(HttpSecurity http) {
	http
		.formLogin(withDefaults());
	// ...
}

별도의 로그인 페이지로 가기 위해서, 다음 코드를 사용 가능하다

public SecurityFilterChain filterChain(HttpSecurity http) {
	http
		.formLogin(form -> form
			.loginPage("/login")
			.permitAll()
		);
	// ...
}

이때 로그인 페이지를 구성하기 위해 몇가지 요소가 있다

  • /login 으로 post 요청을 보내야한다
  • username, password 파라미터를 포함하여야한다
  • error 발견시, usernamepassword를 제공하지 못하였음을 알린다
  • logout 발견시 성공적으로 로그아웃됨을 알린다

Basic Authentication

HTTP에서 제공/인증하는 Basic인증방식

WWW-Authentication가 인증되지 않은 Client로 전송


1. 유저가 리소스(/private)에 non-auth한 요청을 전송
2. Spring SecurityFilterSecurityInterceptorAccessDeniedException를 리턴 및 거부
3. non-auth한 요청이므로, ExceptionTranslationFilterStartAuthentication을 시작. BasicAuthenticationEntryPoint의 인스턴스인 구성된 AuthenticationEntryPointWWW-Authenticate header를 전송
RequestCache는 클라이언트가 원래 요청한 요청을 재생할 수 있으므로, 요청을 저장하지 않는 NullRequestCache

Client가 WWW-Authentication을 수신, username/password를 수신


- ApplicationEventPublisherInteractiveAuthenticationSuccessEvent를 등록
- AuthenticationSuccessHandler이 호출
기본적으로 이것은 SimpleUrlAuthenticationSuccessHandler이며, 로그인시 ExceptionTranslationFilter에 저장된 페이지로 리다이렉트
1. username과 password를 제출시,
BasicAuthenticationFilterUsernamePasswordAuthenticationToken를 생성한다
UsernamePasswordAuthenticationToken의 타입은 Authentication이다
이때 username과 password는 HttpServletRequest에서 추출한 정보이다
2. UsernamePasswordAuthenticationTokenAuthenticationManager로 전달되어 인증을 위임한다
3. 실패!
- SecurityContextHolder가 비워짐
- RememberMeServices.loginFail이 호출
- AuthenticationEntryPoint이 호출, WWW-Authenticate를 재전송하도록 지시한다
4. 성공!
- AuthenticationSecurityContextHolder에 등록
- RememberMeServices.loginSuccess이 호출
- BasicAuthenticationFilter이 로직을 지속하기위해 FilterChain.doFilter(request,response)를 호출

코드 참고
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
	http
		// ...
		.httpBasic(withDefaults());
	return http.build();
}

0개의 댓글