주의사항: Acegi Security 1.0.3은 새로운 ACL 모듈의 미리보기 버전을 포함하고 있다.
새로운 ACL 모듈은 기존 ACL 모듈의 대부분을 재작성한 것이다.
새로운 모듈은 org.acegisecurity.acls 패키지에서 찾아볼 수 있으며,
기존 ACL 모듈은 org.acegisecurity.acl에서 찾아볼 수 있다.
우리는 사용자가 새로운 ACL 모듈을 테스트하고 그것을 이용하여 애플리케이션을
구축할 것을 권장한다. 기존 ACL 모듈은 비추천되어야 하며 차후 릴리즈에서는
제거될 것이다. 다음은 새로운 ACL 모듈에 관련된 정보들이며 따라서
이 버전의 ACL 모듈을 사용할 것을 권장한다.
종종 복잡한 애플리케이션은 단지 웹 요청이나 메소드 호출 수준에서가 아닌
접근 권한을 정의할 필요가 있을 것이다. 대신 보안 결정은
누가(Authentication)와
어디에서(MethodInvocation), 그리고
무엇(SomeDomainObject)으로 구성될 필요가 있다.
다시 말해 인증 결정은 메소드 호출의 대상인 실제 도메인 객체 인스턴스를
고려할 필요도 있다는 것이다.
여러분이 애완동물 병원에서 사용될 애플리케이션을 설계한다고 생각해 보자. 여러분이 작성하는 Spring 기반의 애플리케이션에는 두 개의 주요 사용자 그룹이 있을 것이며, 이러한 사용자 그룹에는 애완동물 병원의 고객은 물론 애완동물 병원의 직원도 포함될 것이다. 고객들이 자기 자신의 기록만을 볼 수 있는 반면 직원들은 모든 자료에 접근할 수 있을 것이다. 좀 더 재미있게 만들기 위해 고객들은 다른 고객들이 자신의 고객 기록을 볼 수 있도록 해줄 수도 있는데, 가령 "바둑이 보육원"의 멘토나 지역 "조랑말 클럽"의 회장에게는 그렇게 해줄 수도 있을 것이다. Acegi Security를 기반으로 사용하면 여러분은 이러한 상황에서 사용할 수 있는 몇 가지 접근법을 갖추게 될 것이다:
여러분의 비즈니스 메소드가 보안을 집행하도록 작성한다. 여러분은
Customer 도메인 객체의 인스턴스내의 컬렉션을
조회하여 어떤 사용자가 접근권한을 갖고 있는지를 확인할 수 있다.
SecurityContextHolder.getContext().getAuthentication()
메소드 호출을 통해 여러분은 Authentication 객체에
접근할 수 있을 것이다.
AccessDecisionVoter가 보안을 집행하도록 작성하여
Authentication 객체에
GrantedAuthority[]를 저장되도록 할 수 있다. 이는 여러분의
AuthenticationManager에서
인증 주체가 접근하는 각각의 Customer 도메인 객체 인스턴스를
나타내는 GrantedAuthority[]들을
Authentication에 들어가게 해야 한다는 것을 의미한다.
대상 Customer 도메인 객체를 직접 개방하도록 작성한다.
이렇게 하는 것은 여러분의 투표자가 Customer 객체를
검색할 수 있도록 해주는 DAO에 접근할 필요가 있다는 것을 의미한다.
그런 다음 Customer 객체에 포함되어 있는
승인된 사용자에 대한 컬렉션에 접근하여 적절한 결정을 내릴 것이다.
각각의 이러한 접근법들은 더할 나위 없이 합리적이다.
하지만 첫 번째 접근법은 인증확인을 여러분의 비즈니스 코드에 결합시킨다.
이러한 접근법의 가장 큰 문제는 단위 테스트를 수행하기가 어렵다는 것과
Customer 인증 로직을 다른 곳에서 재사용하기가 훨씬
더 어려워진다는 것이다. Authentication 객체로부터
GrantedAuthority[]를 획득하는 것은 괜찮지만,
Customer의 수를 크게 늘리지는 않도록 한다.
만약 사용자가 5,000개의 Customer 객체에
접근할 수 있게 되면(이 경우에는 그렇게 되지 않겠지만,
대형 조랑말 클럽의 인기있는 수의사의 경우를 상상해 보자),
Authentication 객체를 생성하기 위해 소비되는 메모리의 양과 시간은
바람직하지 못한 정도가 될 것이다. 외부 코드에서
Customer 객체에 직접 접근하는 마지막 메소드는
아마도 세 가지 메소드 중에서 가장 나은 메소드일 것이다.
이 메소드는 관심의 분리를 달성하고, 그리고 메모리나 CPU 사이클을
오용하지는 않지만, AccessDecisionVoter와 결과적으로 비즈니스 메소드가
직접 Customer 객체를 검색하는 것을 책임지는 DAO에 대한 호출을
수행한다는 점에서 비효율적이다. 메소드 호출을 한 번 할 때마다 두 번씩
접근하는 것은 확실히 바람직하지 못하다. 추가적으로 여러분은 나열한 모든 접근법들을
이용하여 자체적인 접근 제어 목록 영속화 및 비즈니스 로직을 직접 작성해야 할 것이다.
운 좋게도 다른 대안이 있는데, 이에 관해서는 아래에서 이야기하도록 하겠다.