본문 바로가기
Spring/Spring Security

Security 메커니즘

by doriver 2024. 10. 12.

Security는 요청을 처리하기 위해 필터 체인을 구성
다양한 필터로 구성되어 있으며, 각 필터는 요청을 처리하는 특정 기능을 담당

 

FilterChainProxy : 모든 필터를 관리하고 요청을 처리

 

스프링 시큐리티는 총 3가지의 계층(web,service, domain)에 대한 인가 처리를 지원한다.

웹 계층 URL 요청에 따른 인가 처리
서비스 계층 메소드 단위의 인가처리
도메인 계층 객체 단위의 인가처리

 

FilterSecurityInterceptor( -> AuthorizationFilter로 변경됨 )

시큐리티 필터들 중 마지막에 위치하며 특정 요청 승인/거부 최종 결정
SecurityContextHolder에 Authentication 객체가 없거나, 적절한 권한이 없으면 예외를 발생시킴

 

 

 

인증, 권한 기능 

>> 필터에서 요청을 막느냐, 통과시키느냐
>> 통과시킬땐 SecurityContextHolder의 SecurityContext에 Authentication객체를 담아야함

UserDetails( 사용자 정보, 권한 )가 들어있는 Authentication객체
SecurityContextHolder의 ThreadLocal이 Authentication을 한 쓰레드 내에서 공유를 가능하게 함

 

 

SpringSecurity에서 인증, 권한 

인증이 되기 위해선 1,2 를 만족해야하고, 권한이 인정받기 위해선 1,2,3 모두 만족해야함

1. SecurityContextHolder의 SecurityContext에 Authentication객체가 있어야함

SecurityContextHolder.getContext().getAuthentication();

 위 메서드를 호출했을 때 Authentication 객체가 반환어야함  

2. Authentication 객체의 isAuthenticated()가 true여야 함

3. Authentication 객체에 USER 권한이 포함되어 있어야 함
Authentication 객체의 getAuthorities() 메서드가 반환하는 GrantedAuthority 목록에 ROLE_USER가 포함되어 있어야 함

 

인증 확인 단계( SpringSecurity는 default로 session방식으로 인증을 처리 )

요청이 들어올 때 HttpSession에서 SecurityContext를 가져와 인증 상태를 확인하는 것은  SecurityContextPersistenceFilter에서 이루어진다.

session기능을 끄고 jwt로 인증구현할수도 있다

 

인증되지 않은 경우

ExceptionTranslationFilter가 동작하여 인증되지 않은 요청을 처리하기 위해 

AuthenticationEntryPoint를 호출

 

 

 

폼 로그인

formLogin()을 추가하는 경우  폼 로그인(UsernamePasswordAuthenticationFilter)이 활성화
사용자가 /login으로 POST 요청 (username, password 포함)
> UsernamePasswordAuthenticationFilter에서 인증 수행
> AuthenticationManager를 사용하여 입력된 자격 증명을 검증한다.

자격 증명 검증이 실패하면(예: 잘못된 아이디 또는 비밀번호) 
UsernamePasswordAuthenticationFilter는 AuthenticationFailureHandler를 호출
AuthenticationFailureHandler가 실패 상황을 처리

인증이 성공하면 Authentication 객체를 생성하여 SecurityContextHolder에 저장
이후, AuthenticationSuccessHandler를 호출하여 로그인 성공 처리

요청이 끝날 때 SecurityContextPersistenceFilter가 SecurityContext를 확인.

HttpSessionSecurityContextRepository를 통해 SecurityContext를 세션에 저장

formLogin()을 추가하지 않는 경우 UsernamePasswordAuthenticationFilter가 동작하지 않음