[Spring] Spring Security (2)

한호성·2022년 12월 2일
0

글의 목적

이전 글에서 Spring Security 의 Authentication (인증) 에 대해 알아보았다.
요번 글에서는 Authorization (인가) 에 대해 작성하도록 하겠다.

Authorization 개념

  • 사용자가 특정 자원에 접근하고자 요청(Request) 하면 , 그 사용자가 인증을 받았는지 확인한다.
  • 인증을 받은 사용자라면 해당 사용자의 자격이 해당 자원에 접근할 자격이 되는지 확인한다.

위 사진에서 볼 때, 인증을 마친 후 , 인가를 진행하고, 각 회원의 ROLE_*; 값에 따라 접근할 수 있는 영역이 달라지는 것을 확인할 수 있다.

스프링 시큐리티가 지원하는 권한 계층

  1. 웹 계층
    • URL 요청에 따른 메뉴 혹은 화면단위의 레벨 보안
    • /user 경로로 자원 접근을 할 때, 그 자원에 설정된 권한과 사용자가 가진 권한을 서로 심사해서 결정하는 계층
  2. 서비스 계층
    • 화면 단위가 아닌 메소드 같은 기능 단위의 레벨 보안
    • user() 라는 메소드에 접근하고자 할 때, 해당 메소드에 설정된 권한과 사용자가 가진 권한을 서로 심사해서 결정하는 계층
  3. 도메인 계층 (Access Control List, 접근 제어 목록)
    • 객체 단위의 레벨 보안
    • 객체를 핸들링 하고자 할 때, 도메인에 설정된 권한과 사용자가 가진 권한을 서로 심사해서 결정하는 계층 ( 이 부분은 어떤 의미인지 잘 모르겠다..)

FilterSecurityInterceptor - 인가 처리 담당 필터

  • 필터 체인에서 가장 마지막에 위치한 필터로써, 인증된 사용자에 대한 특정 요청의 승인 및 거부를 최종적으로 결정
  • 인증객체 없이 보호자원에 접근을 시도하면 AuthenticationException 발생
  • 인증 후 , 자원에 접근 가능한 권한이 존재하지 않을 경우 AccessDeniedException 읇 ㅏㄹ생
  • 권한 처리를 AccessDecisionManager 에게 맡긴다.

인가 Flow

1. 사용자가 자원 접근 (Request)
2. FilterSecurityInterceptor 에서 요청을 받아서 인증여부 확인
	a. 인증객체를 가지고 있는지 확인
    b. 인증객체가 없으면 null AuthenticationException 발생
    c. Excetpion TranslationFilter 에서 해당 예외를 받아 로그인 페이지 이동 
    or 알아서 후처리 해준다.
3. 인증객체가 있을 경우, SecurityMetadataSource는 자원에 접근하기 위해 설정된 
권한정보를 조회해서 전달해준다.
	a. 권한 정보를 조회한다.
    b. 권한 정보가 없으면 null 권한 심사를 하지 않고 자원 접근 허용
4. 권한 정보가 있을 경우 AccessDecisionManager에게 권한 정보를 
전달하여 위임한다.
	-> AccessDecisionManager는 최종 심의 결정자다.
5. AccessDecisionManger 가 내부적으로 AccessDecisionVoter(심의자)를 
통해서 심의 요청을 한다.
6. 반환된 승인/거부 결과를 가지고 사용자가 해당 자원에 접근 가능한지 판단.
	a. 접근이 거부되었을 경우 AccessDeniedException이 발생한다
    b. Exception TranslationFilter에서 해당 예외를 받아서 다시 후처리
7. 접근이 승인되었을 경우 자원 접근 허용

인가 결정 심의자 (Access DecisionManger , AccessDecisionVoter)

AccessDecisionManager ::인터페이스

  • 인증 권한 정보를 이용해서 , 사용자의 자원접근을 허용/거부 여부를 최종 결정하는 주체다.
  • 여러 개의 Voter 들을 가질 수 있고 , Voter들로부터 접근허용.거부.보류에 해당하는 각각의 값을 리턴받아 판단 & 결정한다.
  • 최종 접근 거부시 예외 발생.

-> 접근결정의 세가지 유형 ::구현체

  1. AffirmativeBased :: OR 연산자와 같은 논리
    • 여러개의 Voter 클래스 중 하나라도 접근 허가로 결론을 내면 접근 허가로 판단.
  2. ConsensusBased :: 다수결
    • 다수표에 의해 최종 결정 판단
  3. Unanimousased :: AND 와 동일한 논리
    • 모든 Voter가 만장일치로 접근을 승인해야 하며, 그렇지 않은 경우 접근을 거부한다.

AccessDecisionVoter
- 판단을 심사하는 것 (위원)
- 각각의 Voter 마다 사용자의 요청마다 해당 자원에 접근할 권한이 있는지 판단 후, AccessDecisionMager 에게 반환하는 역할

Voter가 권한 부여 과정에서 판단하는 자료 - 아래 정보를 전달받아 판단.

  • Autehntication - 인증정보(user)
  • FilterInvocator - 요청 정보 (antMatcher("/user"))
  • ConfigAttributes - 권한 정보 (hasRole("USER"))

-> 결정 방식 - AccessDecisionMager은 반환 받은 결정 방식을 사용해서 후처리를 한다.

  • ACCESS_GRANTED : 접근 허용 (1)
  • ACCESS_Denied : 접근 거부(-1)
  • ACCESS_ABSTAIN : 접근 보류(0)
    - Voter가 해당 타입의 요청에 대해 결정을 내릴 수 없는 경우

AccessDecisionVoter Flow

1. FilterSecurityInterceptor 가 AccessDecisionManger 에 인가 처리 위임
2. AccessDecisionManger 는 자신이 가지고 있는 Voter 들에게 정보 Decide
(authentication, Object, ConfigAttributes)를 전달
3. Voter 들은 정보들을 가지고 권한 판단을 심사한다.
4. 승인 거부,보류 결정방식을 반환하면 AccessDecisionManager에서는 반환받은 
결정 방식을 가지고 후처리를 진행한다.
	A. 승인 : FilterSecurityIntercepteor에 승인여부 반환
    B. 거부 : AccessDeniedException 예외를 ExceptionTranslationFilter로 전달

Reference

정말 세세하게 잘 정리되어 있다.
https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0
(정말 정리 잘되있다.. 참고해서 직접 Security 코드 따라다니면서 확인하면 이해하기 유용)

profile
개발자 지망생입니다.

0개의 댓글