본문 바로가기

Spring

Spring Security


보안 관련 3요소


  1. 접근 주체(Principal) : 보호된 대상에 접근하는 사용자

  2. 인증(authentication) : 사용자의 신원을 식별하는 기능. ex) 로그인 기능

  3. 인가(authorization) : 권한 관리 기능. ex) role


# 인증(authentication) 방식

 1. credential 기반 인증 : 사용자명과 비밀번호를 이용.

 2. 이중 인증 : 사용자가 입력한 개인정보를 인증 후, 다른 인증 체계를 이용하여 두가지의 조합으로 인증.

 3. 하드웨어 인증 : 자동차 키와 같은 방식.


이 중 Spring Security는 credential 기반의 인증을 취한다. principal : 아이디 / credential : 비밀번호 





Spring Security 구조


Spring Security : authentication 기능, authorization 기능, 보안 공격에 대한 보호 기능 등이 잘 구현된 프레임웍


spring security 에서 권한(authorization)은 다음과 같이 표현하는 것이 관례다.

                     예) ROLE_ADMIN, ROLE_PROFESSOR, ROLE_STUDENT



 #인증 아키텍쳐




 #Authentication Manager 구조




# 인증 순서


1. 유저 로그인


2. UserDetailsService.loadUserByUsername으로 DB에서 유저 조회 결과를 AuthencationProvider로 리턴. 


3. AuthencationProviderauthenticate메소드에서 접속한 유저가 입력한 비번과      UserDetailsService.loadUserByUsername(String username) 메소드로 가지고온 디비유저정보와 비교.


4. 인증에 성공하게 되면 authenticate메소드에서 Authentication 객체를 리턴.

Authentication 객체는 스프링에서 구현해놓은 UsernamePasswordAuthenticationToken 사용해도 무방.

UsernamePasswordAuthenticationToken(UserDetailsService.loadUserByUsername(String username),null(보통),권한) 을 생성하게되면, Authentication이 생성되어지고 최종적으로 이것을 리턴해주면서 security 인증이 끝남.




# Spring Security 주요 컴포넌트


SecurityContextHolder , SecurityContext , Authentication 

위 세가지 클래스는 Spring Security에서 주요 컴포넌트.


1. Authentication 

- 현재 접근 주체(Principal)의 정보를 담는 목적

- 인증을 요청할 때, 요청 정보 담는 목적

- 주요 메서드

- String getName() : 사용자의 이름

- Object getPrincipal() : 인증 주체 정보

- Object getCredential() : 비밀번호 등

- boolean isAuthenticated() : 인증되었는지 여부

- Collection<GrantedAuthority> getAuthorities() : 현재 사용자가 가진 권한(GrantedAuthority)



2. SecurityContext

 - Authentication 보관

- Spring Security는 현재 사용자에 대한 Authentication 객체를 구할 때 SecurityContext로부터 구함.



3. SecurityContextHolder

- SecurityContext 보관




# 시각화


아이디/패스워드 사용자 정보를 넣고 실제 가입된 사용자인지 체크한후 인증에 성공하면,

사용자의 principalcredential 정보를 Authentication에 담는다.



 방금 담은 AuthenticationSecurityContext에 보관.


                                                            


SecurityContextSecurityContextHolder에 담아 보관.


정리 : 

현재 사용자의 정보를 가지고 있는 principal을 가져오려면 => Authentication에서 가져온다.

AuthenticationSecurityContext에서 가져온다.

SecurityContextSecurityContextHolder에서 가져온다.


따라서 Spring Security에서 현재 사용자의 유저를 가져오는 방법은 다음과 같다.

SecurityContextHolder.getContext().getAuthentication().getPrincipal();



# Spring Security는 세션-쿠키방식으로 인증.


전통적인 쿠키-세션 방식을 사용. (JWT는 spring-security-oauth2..)

    1. 1. 유저가 로그인을 시도 (http request)
    2. 2. AuthenticationFilter 에서부터 user DB까지 타고 들어감.
    3. 3. DB에 있는 유저라면 UserDetailsService 로 꺼내서 유저의 session 생성.
    4. 4. Spring Security의 인메모리 세션저장소인 SecurityContextHolder 에 저장.
    5. 5. 유저에게 session ID와 함께 응답을 내려줌.
    6. 6. 이후 요청에서는 요청쿠키에서 JSESSIONID를 까봐서 검증 후 유효하면 Authentication를 쥐어준다.

아래는 로그인 성공 상황인데, 익명세션ID에서 security가 내려주는 유효한 세션ID로 뒤바뀌는 장면





# Spring Security는 Servlet Filter 기반으로 동작.

그림 설명 :

Spring Security Filter는 A Filter의 일을 수행하고, 다음 B Filter의 일을 수행하는 

A -> B -> C Filter 의 Chain 형식.

한 요청에 대해 filter들이 순차적으로 일을 수행한다.

필터들이 순차적으로 요청되면서 doFilter 메소드가 수행된다.



# Filter 종류

필터설명
SecurityContextPersistenceFilter

(Authentication 로딩)

SecurityContextRepository에서 SecurityContext를 로드하고
저장하는 일을 담당

LogoutFilter

(로그아웃 요청 처리)

로그아웃 URL로 지정된 가상URL에 대한 요청을 감시하고
매칭되는 요청이 있으면 사용자를 로그아웃시킴

UsernamePasswordAuthenticationFilter

(인증 요청 처리)

사용자명과 비밀번호로 이뤄진 폼기반 인증에 사용하는
가상 URL요청을 감시하고 요청이 있으면 사용자의 인증을 진행

DefaultLoginPageGeneratingFilter

(로그인 폼 출력)

폼기반 또는 OpenID 기반 인증에 사용하는 가상URL에 대한 요청을
감시하고 로그인 폼 기능을 수행하는데 필요한 HTML을 생성함

BasicAuthenticationFilter

HTTP 기본 인증 헤더를 감시하고 이를 처리함

RequestCacheAwareFilter

로그인 성공 이후 인증 요청에 의해 가로채어진 사용자의 원래
요청을 재구성하는데 사용됨. 

SecurityContextHolderAwareRequestFilter HttpServletRequest를 HttpServletRequestWrapper를 상속하는 하위 클래스(SecurityContextHolderAwareRequestWrapper)로 감싸서 

필터 체인상 하단에 위치한 요청 프로세서에 추가 컨텍스트를 제공.

AnonymousAuthenticationFilter(임의 사용자 처리)
이 필터가 호출되는 시점까지 사용자가 아직 인증을 받지 못했다면
요청 관련 인증 토큰에서 사용자가 익명 사용자로 나타나게 됨
SessionManagementFilter인증된 주체를 바탕으로 세션 트래킹을 처리해 단일 주체와
관련한 모든 세션들이 트래킹되도록 도움
ExceptionTranslationFilter(익셉션 처리)
이 필터는 보호된 요청을 처리하는 동안 발생할 수 있는 기대한
예외의 기본 라우팅과 위임을 처리함
FilterSecurityInterceptor

(접근 권한 검사)

이 필터는 권한부여와 관련한 결정을 AccessDecisionManager에게
위임해 권한부여 결정 및 접근 제어 결정을 쉽게 만들어 줌

필터 체인의 제일 마지막에 위치한 FilterSecurityInterceptor는 앞에 지나온 모든 필터들의 정보를 토대로 최종 결정을 내린다.



참고


'Spring' 카테고리의 다른 글

@Setter  (0) 2019.04.18
토비의 스프링3.1 - 템플릿 메소드 패턴, 팩토리 메소드 패턴  (0) 2019.03.03
Spring Security + Spring MVC  (0) 2019.02.04
spring core(핵심) 기능  (0) 2019.01.31
ModelAttribute  (0) 2019.01.30