Build Up
- AOP는 관심사가 같은 코드들을 모듈화 하는 역할을 한다.
- SpringSecurity 여러 인증과 권한 절차를 거쳐 진행한다.
- 인증과 권한처리는 여러 FilterChainProxy라는 곳에서 여러 필터들을 거치면서 처리한다.
- 특히 권한처리는 FilterSecurityInterceptor에서 일어난다.
What
권한 처리를 할때, AccessDecisionManager가 있으며 Method 권한 판정은 하나의 Global 위원회에서 처리한다. 권환 위원회라는 개념을 만들었다.

AccessDecisionManager는 권환위원회이다.
AffirmativeBased : 긍정위원회는 1명만 통과해도 통과이다.
ConsensusBased : 다수결 위원회로 다수가 통과해야 통과한다.
UnanimouseBased : 만장일치 위원회로 모두가 통과해야 한다.

권한은 SecurityInterceptor에서 검사를 시작하는데, Invocation 대상이 AccessDecisinManager에게 넘겨져 평가를 받게 된다. decide()로 평가를 해서 GRANT 할지 DENY를 할지 정한다. AuthentiationProvider가 supports()를 가지고 있는것처럼 AccessDecisionVoter도 supports() 메서드를 가지고 있다. 해당 ConfigAttribute를 가지고, 지금 조건을 너가 처리해줄 수 있니? 라고 질문을 한다. DecisionManager들이 DecisionVoter들에게 물어보고 가능하다면 vote() 하도록 한다. 그 결과를 취합해서 pass / AccessDeny를 구분한다.
사실, accessDecisionManager에서 decide()만 구현해도 된다. vote()까지 꼭 구현할 필요는 없다. 기본적으로 스프링 시큐리티는 vote() 기반이기 때문에, @PreAuthorize 같은 기능들은 vote() 기반으로 사용하게끔 설계해주면 된다.

SecurtyInterceptor에 AccessDecisionManager가 있고, voter들을 데리고 접근 권한을 판정한다. 이 때, AuthenticationManager는 재검증을 수행할 수도 있다. RunAsManager로 임시 권한을 부여하는 장치를 둔다.
이 처리는 FilterSecurityInterceptor 혹은 MethodSecurityInterceptor에서도 동일하다. 권한 판정을 하기 위해서 ConfigAttribute가 필요한데, 이것을 모아놓은 map이 SecurityMetadataSource이다. 각각 다른 metadataSource를 가지고 있다.
코드기반으로 살펴보기
- 권한처리는 FilterSecurityInterceptor의 Invoke method를 시작으로 이루어진다.

- super.beforeInvocation을 통해 미리 사전 검수가 이루어진다 (즉 권한 처리가 이루어진다는 뜻이다.)

- super.beforeInvocation은 인증과정을 다시 한번 재검사후 attemptAuthorization 메소드를 호출하여 권한검사가 실제로 이루어진다.

- attemptAuthorization 내부를 보면 decide(=결정하다) 라는 메서드를 호출하여 해당 권한 여부가 적절한 접근인지 판단하기 시작한다.

- 기본적으로 AccessDecisionManager의 DEFAULT 설정은 AffirmativeBased를 바탕으로 이루어진다.

- AffirmativeBased decide에서 Voter들이 출동하여 권한 검사 여부를 판단한다.
- 나는 PreInvocationVoter만이 있다. [PreAuthorize 사용]

- PreInvocationVoter.vote를 통해 int형으로 반환을 하고 decide에서 거부할지 통과할지 결정하게 된다.

