FilterSecurityInterceptor
는 SecruityContextHolder
로 부터 Authentication
을 얻습니다.FilterSecurityInterceptor
는 FilterInvocation
을 생성합니다.SecurityMetadataSource
에 FilterInvociation
을 전달 하고 ConfigAttrubite
를 생성합니다.Authentication
, ConfigAttribute
를 AccessDescisionManager
에 전달합니다.AccessDescisionManager
는 decide(Authentiaction, Collection)
메서드를 호출하여 다수의 AccessDescisionVoter
에게 처리를 위임합니다.AccessDescisionVoter
는 Authentication
과 ConfigAttribute
를 비교하여 승인, 거부, 기권 여부를 AccessEscisionManager
에게 전달합니다.AccessDescisionManager
는 AccessDesicionVoter
들의 판단 여부를 종합하여 정책에 맞게 판단을 합니다.인증
,요청
,권한
정보를 이용하여 사용자의 자원접근 여부를 허가, 거부를 결장하는 최종 주체입니다. 여러개의 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에서 시큐리티 인터셉터가 제출할 보안 객체 타입을 지원하는 지 확인합니다.AffirmativeBased
: OR
연산자와 비슷Voter
클래스 중 하나라도 허가
로 결론을 내리면 접근 허가로 판단합니다.ConsensusBased
: 다수결Voter
가 기권일 경우 allowIfEqualGeneratedDeniedDescision
을 false
이면 접근 거부로 됩니다.UnanimousBased
: AND
연산자와 비슷Voter
가 만장일치로 접근을 승인해야만 승인, 하나 라도 반대가 있을 경우 접근을 거부합니다.판단을 심사하는 클래스로써 AccessDecisionManager
에게 판단을 위임받고 결과를 반환하는 역할을 수행합니다.
AccessDecisionManager
의 decide()
메서드의 호출로 전달받은 자료들을 판단하여 되돌려 주는 값은 AccessDescisionVoter
의 상수를 반환합니다.
상수 | 설명 |
---|---|
ACCESS_GRANTED | 접근 허용(1) |
ACCESS_DENIED | 접근 거부(-1) |
ACCESS_ABSTAIN | 접근 보류(0) |
잘 정리된 설명이어서 첨부하였습니다.
스프링 시큐리티는 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 객체에 직접 접근할 수 있습니다. |
authentication | SecurityContext로 조회할 수 있는 현재 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') |
@Pre
와 @Post
애너테이션을 활용하여 사전/사후 권한 체크, 리턴한 값을 필터링 할 수도 있습니다. @PreAuthorize
, @PreFilter
, @PostAuthorize
, @PostFilter
애터네이션이 존재합니다.
Method Security | 설명 |
---|---|
@PreAuthorize("표현식") | 메서드를 실행하기 전에 권한을 확인합니다. |
@PostAuthorize("표현식") | 메서드를 실행한 다음에 권한을 확인합니다. |
@PreFilter | 흔한 요구사항은 아니지만 메서드 호출전에 필터링합니다. |
@PostFilter | 표현식 결과가 false인 모든 요소를 제거한 후 반환합니다. |
어제는 인증에대하여 학습하였고 오늘은 인증한 사용자에 대하여 인가를 하는 절차에 대해학습하였습니다. 보안은 역시 깊숙히 파고들기엔 추상적은 개념도 많고 잘 정리된 자료를 찾기도 어려운 것 같습니다.
없음!