스프링 시큐리티 커스텀 ACL 등록하기.
Spring2010. 4. 28. 12:45
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);
}
}
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);
}
* 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 설정 역시 머리가 아팠는데... 영어 문서의 압박과 구버전 샘플의 압박.
요리 저리 디버깅 해가면서 조금은 더 알게 되었다.
대충 구조를 살펴 보면 아래와 같은 구조를 가지게 된다.

그럼 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>
<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 등록 안될경우 발생하는 오류) 이런 오류는 표시되지 않게 된다.