권한은 기본적으로 AccessDecisionManager를 구현해서 처리할 수 있다. 하지만 기존에 잘 구현된 소스들을 사용하려면 Voter 기반의 AccessDecisionManager를 사용하는 것이 좋다. 기존의 구현체에는 아래의 세가지가 있다.
AccessDecisionManager : 권한 위원회
각각의 기능은 각 클래스의 decide() 메소드를 보면 쉽게 확인할 수 있다.
Role 기반의 권한은 리눅스부터 아파치, 톰캣 등 IT 초기부터 전통적으로 구현해서 사용하던 가장 직관적인 권한 체계이다. 하지만, Role을 기반으로 권한을 판단하기엔, 상황이 너무 다양해졌다. 그래서 Role을 확장한 Authority 기반의 권한 체계를 사용하고 있다. 그렇지만, 기존의 Role 기반이 가지고 있는 직관적이고 계층적인 사용성을 그대로 사용할 수 있도록 해주기 위해 RoleVoter가 쓰인다.
인증(통행증)을 받았다면 그 인증의 종류가 어떤 종류인지를 판단한다. 이제 막 인증을 받고 들어온 사용자와 RememberMe 토큰을 통해서 들어온 사용자와 익명 사용자를 구분하기 위해 쓰인다. RememberMe 인증 사용자는 탈취된 토큰을 가지고 들어온 사용자일 수 있기 때문에 필요한 경우 한번 더 인증을 요구할 수 있다.
하지만 RoleVoter는 SpEL을 사용하는 WebExpressionVoter나 PIAAVoter(PreInvocationAuthorizationAdviceVoter)가 사용성을 대체하고 있다.
Spring Expression Language는 표현식을 통해 객체의 값을 가져오거나 동작을 시켜주는 기능을 한다. 사실상 컴파일 언어라고 할 수 있는 자바를 스크립트 언어처럼 동작하게 해주는 기능이다.
이제까지의 권한 검사는 Authentication 통행증을 검사하는 것이었다. 그런데 심사를 하려면 통행증만 검사하면 안되고, 가져가려는 물건이 무엇인지를 같이 봐야하는 경우가 많다.
가령 기말 고사 시험지를 작성중이라고 해보자.
이런 경우라면 당연히 어떤 시험지인지, 그리고 그 시험지에 대한 열람 권한이 누구에게 있는지... 여러가지 데이터들이 모여야 해당 권한을 판단할 수가 있다. 이런 경우에는 PermissionEvaluator를 사용하거나 객체별로 접근 권한을 DB로 관리해주는 ACL처럼 권한을 체크하기 위한 별도의 설계가 들어가야 한다.
WebExpressionVoter와 PIIAVoter는 모두 아래와 같은 방식으로 SpEL을 사용한다.
참고