Clean Code that Works.


private PermissionFactory permissionFactory = new DefaultPermissionFactory();이전 포스트에서 보았던 블로그 샘플을 보면, 커스텀 ACL을 등록해서 사용 하는 것을  볼 수 있다.

public class ExtendedPermission extends BasePermission {

    private static final long serialVersionUID = 1L;
    public static final Permission ACCEPT = new ExtendedPermission( 1 << 5, 'a'); // 32
    public static final Permission WRITE_CREATE = new ExtendedPermission( 1 << 6, 'E'); // 64
   
    protected ExtendedPermission( int mask, char code) {
        super( mask, code);
    }
}

이렇게 원하는 권한을 만든 후에, 이것을 스프링에게 알려줘야 하는데..
2.0 버전에는 아래의 BasePermission.registerPermissionFor() 메서드를 호출해서 새로 등록한 퍼미션 클래스를 등록하면 됬었다.

/**
* Registers the public static permissions defined on this class. This is
* mandatory so that the static methods will operate correctly. (copied from
* super class)
*/
static {
registerPermissionsFor(ExtendedPermission.class);
}

하지만 3.0 버전으로 넘어 오면서 패키지 구조가 많이 바뀌고, 이로 인해 메서드들도 바뀌게 되었다.(햇갈려!!!)

하여, 위의 registerPermissionFor 는 사라지고(다른 클래스로 옴겨가고)
이를 해결 하기 위하여,
PermissionFactory를 구현한 Concrete Class 인 DefaultPermissionFactory의 registerPublicPermissions() 메서드가 있다.

바로 registerPublicPermissions() 메서드가 내부적으로 registerPermission을 호출 해서 스프링에 등록이 되는 것이다.(이 표현이 맞나.. 아무튼 레지스트리에)
하여 이를 사용해서 등록을 해야 하는데, DefaultPermissionFactory의 생성자 중 하나인
/**
     * Registers the <tt>Permission</tt> fields from the supplied class.
     */
    public DefaultPermissionFactory(Class<? extends Permission> permissionClass) {
        registerPublicPermissions(permissionClass);
    }

요것을 통해서 Permission 클래스를 상속 받은(ExtendedPermission) 클래스를 파라미터로 넘겨 주면 이를 등록하게 된다.

이렇게 해서 ExtenedPermission을 등록 할 수 있는데, 그럼 과연 DefaultPermissionFactory는 어디서 등록을 해야 하는가.
이거 찾느라 시간을 너무 허비..덕분에 acl에 대해 좀 더 알 수 있었다.

바로 BasicLookupStrategy에 permissionFactory에다가 DefaultPermissionFactory를 등록 하면 된다.
위 클래스의 소스를 보면 알겠지만 기본적으로
private PermissionFactory permissionFactory = new DefaultPermissionFactory();
이렇게 해서 사용 하고 있다. 이걸 new DefaultPermissionFactory(ExtendedPermissionFactory.class); 로 바꿔주어야 하는데,
XML 설정 파일을 통해서 변경 할 수 있다.

시큐리티 설정을 위한 XML 설정 역시 머리가 아팠는데... 영어 문서의 압박과 구버전 샘플의 압박.
요리 저리 디버깅 해가면서 조금은 더 알게 되었다.

대충 구조를 살펴 보면 아래와 같은 구조를 가지게 된다.

XML 설정 구조


그럼 lookupStrategy를 어디에다가 등록을 하는가 하면
aclService의 구현클래스의 변수인 lookupStragegy에다가 등록을 해 주면 된다.

 <bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
        <constructor-arg ref="dataSource"/>
        <constructor-arg ref="aclCache"/>
        <constructor-arg ref="aclAuthorizationStrategy"/>
        <constructor-arg>
            <bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
        </constructor-arg>
        <property name="permissionFactory">
            <bean class="org.springframework.security.acls.domain.DefaultPermissionFactory">
                <constructor-arg value="net.study.spring.test.security.ExtendedPermission"/>
            </bean>
        </property>
    </bean>

이렇게 등록을 하면 스프링이 올라갈때, 커스텀된 권한까지 가지고 올라가기 때문에 acl_entry 테이블의 mask에 등록된 커스텀 acl 값이 잘 올라가고, Mask '32' does not have a corresponding static Permission(커스텀 acl 등록 안될경우 발생하는 오류) 이런 오류는 표시되지 않게 된다.