[62일차]Authorization 절차, AccessDescisionManager, AccessDescisionVoter, 표현식 기반 접근 제어

유태형·2022년 7월 26일
0

코드스테이츠

목록 보기
62/77

오늘의 목표

  1. Authorizaiton 절차
  2. AccessDecisionManager
  3. AccessDecisionVoter
  4. 표현식 기반 접근 제어



내용

Authroization 절차

  1. 사용자가 HTTP요청을 보냅니다.
  2. FilterSecurityInterceptorSecruityContextHolder로 부터 Authentication을 얻습니다.
  3. FilterSecurityInterceptorFilterInvocation을 생성합니다.
  4. SecurityMetadataSourceFilterInvociation을 전달 하고 ConfigAttrubite를 생성합니다.
  5. Authentication, ConfigAttributeAccessDescisionManager에 전달합니다.
  6. AccessDescisionManagerdecide(Authentiaction, Collection)메서드를 호출하여 다수의 AccessDescisionVoter에게 처리를 위임합니다.
  7. AccessDescisionVoterAuthenticationConfigAttribute를 비교하여 승인, 거부, 기권 여부를 AccessEscisionManager에게 전달합니다.
  8. AccessDescisionManagerAccessDesicionVoter들의 판단 여부를 종합하여 정책에 맞게 판단을 합니다.



AccessDecisionManager

인증,요청,권한 정보를 이용하여 사용자의 자원접근 여부를 허가, 거부를 결장하는 최종 주체입니다. 여러개의 Voter들을 가질 수 있고 Voter들로 부터 승인,거부,보류에 해당하는 값들을 리턴받아 결정합니다.(최정 접근 거부 시 예외 발생)

void decide(Authentication authentication, Object secureObject, Collection<ConfigAttribute> attrs) throws AccessDeniedException;

boolean supports(ConfigAttribute attribute);

boolean supports(Class clazz);
  • decide() : AccessDecisionVoter에게 결정 권한을 부여하는데 필요한 정보가 전달됩니다. authentication : 인증 객체, secoureObject : 보안객체, attrs : 권한리스트 입니다.
  • supports(ConfigAttribute) : 기동 시점에 AbstractSecurityInterceptor가 호출하며 AccessDecisionManager가 전달된 ConfigAttribute의 처리 가능 여부 결정
  • supports(Class) : AccessDecisionManager에서 시큐리티 인터셉터가 제출할 보안 객체 타입을 지원하는 지 확인합니다.


접근 결정 유형

  1. AffirmativeBased : OR연산자와 비슷
  • 여러개의 Voter클래스 중 하나라도 허가로 결론을 내리면 접근 허가로 판단합니다.
  1. ConsensusBased : 다수결
  • 다수표로 결정난 최종 결정을 판단합니다.
  • 동수이거나 모든 Voter가 기권일 경우 allowIfEqualGeneratedDeniedDescisionfalse이면 접근 거부로 됩니다.
  1. UnanimousBased : AND연산자와 비슷
  • 모든 Voter가 만장일치로 접근을 승인해야만 승인, 하나 라도 반대가 있을 경우 접근을 거부합니다.



AccessDecisoinVoter

판단을 심사하는 클래스로써 AccessDecisionManager에게 판단을 위임받고 결과를 반환하는 역할을 수행합니다.

AccessDecisionManagerdecide() 메서드의 호출로 전달받은 자료들을 판단하여 되돌려 주는 값은 AccessDescisionVoter의 상수를 반환합니다.

상수설명
ACCESS_GRANTED접근 허용(1)
ACCESS_DENIED접근 거부(-1)
ACCESS_ABSTAIN접근 보류(0)

잘 정리된 설명이어서 첨부하였습니다.




표현식 기반 접근 제어

Common Built-In 표현식

스프링 시큐리티는 EL 표현식을 사용하여 표현식 기반 접근을 제어합니다. SecurityExpressionRoot클래스는 웹과 메서드 시큐리티 전용 클래스를 루트 객체로 사용하기 때문에 별도의 내장 표현식을 사용 가능합니다.

표현식설명
hasRole(String role)현재 보안 주체(principal)가 지정된 역하을 갖고 있는지 여부를 확인하고 가지고 있다면 true를 리턴합니다. hasRole('admin')처럼 파라미터로 넘긴 role이 ROLE_로 싲가하지 않으면 기본적으로 추가합니다.(DefaultWebSecurityExpressionHandler의 defaultRolePrefix로 커스텀 가능)
hasAnyRole(String... role)현재 보안 주체가 지정한 역할 중 1개라도 가지고 있으면 true를 리턴합니다.(문자열 리스트를 콤마로 구분해서 전달) ex) hasAnyRole('admin', 'user')
hasAuthority(String authority)현재 보안 주체가 지정한 권한을 갖고 있는지 여부를 확인하고 가지고 있다면 true를 리턴합니다. ex)hasAuthority('read')
hasAnyAuthority(String... authorities)현재 보안 주체가 지정한 권한 중 하나라도 있으면 true를 리턴합니다. ex)hasAnyAuthority('read','write')
principal현재 사용자를 나타내는 principal 객체에 직접 접근할 수 있습니다.
authenticationSecurityContext로 조회할 수 있는 현재 Authentication 객체에 직접 접근할 수 있습니다.
permitAll항상 true를 반환합니다.
denyAll항상 false를 반환합니다.
isAnonymous()현재 보안 주체가 익명 사용자면 true를 반환합니다.
isRememberMe()현재 보안 주체가 remember-me 사용자면 true를 반환합니다.
isAuthenticated()사용자가 익명이 아닌 경우 true를 반화합니다.
isFullyAuthenticatioed()사용자가 익명 사용자나 remember-me사용자가 아니면 ture를 반환합니다.
hasPermission(Object target, Object permission)사용자가 target에 해당 permission 권한이 있으면 true를 반환합니다. ex)hasPermission(domainObject,'read')
hasPermission(Object targetId, String targetType, Object permission)사용자가 target에 해당 permission권한이 잇으면 true를 리턴합니다. ex)haspermission(1,'com.example.domain.Message','read')


Method Security 표현

@Pre@Post 애너테이션을 활용하여 사전/사후 권한 체크, 리턴한 값을 필터링 할 수도 있습니다. @PreAuthorize, @PreFilter, @PostAuthorize, @PostFilter 애터네이션이 존재합니다.

Method Security설명
@PreAuthorize("표현식")메서드를 실행하기 전에 권한을 확인합니다.
@PostAuthorize("표현식")메서드를 실행한 다음에 권한을 확인합니다.
@PreFilter흔한 요구사항은 아니지만 메서드 호출전에 필터링합니다.
@PostFilter표현식 결과가 false인 모든 요소를 제거한 후 반환합니다.



후기

어제는 인증에대하여 학습하였고 오늘은 인증한 사용자에 대하여 인가를 하는 절차에 대해학습하였습니다. 보안은 역시 깊숙히 파고들기엔 추상적은 개념도 많고 잘 정리된 자료를 찾기도 어려운 것 같습니다.




GitHub

없음!

profile
오늘도 내일도 화이팅!

0개의 댓글