Acegi Security

1 11 2007

Penulis sedang mengerjakan project dengan Acegi Security untuk assign permission pada hak akses. Sudah hampir dua minggu Acegi Security cukup menyulitkan penulis belajar sampai burung kecil berkeliling di atas kepala penulis.😀 Untung, dibantu oleh Pak Endy (Project Manager) dan Dhiku (rekan kerja).

Saat ini menggunakan HSQLDB. Sebelum membuat Acegi Security, terlebih dahulu kita menginstall HSQLDB. Nantinya kita bisa melihat, mengisi ataupun menghapus isi tabel. Di sini penulis tidak membahas cara menginstall HSQLDB, mungkin kalian bisa mencari di manual HSQLDB.

Di sini penulis membahas bagaimana membuat aplikasi contact menggunakan acegi secara sederhana.

Pertama kita membuat class Contact :

Contact.java

public class Contact {
	private Long id;
	private String name;
	private String address;

	public Contact() {}

	public Contact(Long id, String name, String address) {
		this.setId(id);
		this.setName(name);
		this.setAddress(address);
	}
	// setter and getter
}

Setelah membuat di atas, kita membuat implementasi ContactService. Method getAll() akan difilter berdasarkan akses kontrol disimpan di tabel ACL(Access Control List) akan dibuat. User berhak boleh melihat daftar contact yang ada.

ContactService.java

public interface ContactService {
	public Contact getById(Long id);
	public List getAll();

	public void addPermission(Contact contact, Sid recipient, Permission permission);
	public void deletePermission(Contact contact, Sid recipient, Permission permission);
	public void grantPermission(Long id, String recipientName, Permission permission);
}

Selanjutnya, membuat class ContactServiceImpl memiliki 3 method penting untuk assign permission, yaitu addPermission, deletePermission, dan grantPermission. Di mana user berhak memiliki level seperti ADMINISTRATOR, dan READ. Level ADMINISTRATOR dapat menggunakan semua method, sedangkan level READ tidak bisa menggunakan semua method kecuali cuma dapat membaca saja.

ContactServiceImpl.java

@Override
public void addPermission(Contact contact, Sid recipient, Permission permission) {
	MutableAcl acl;
	ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, new Long(contact.getId()));
	acl = (MutableAcl) mutableAclService.readAclById(oid);
	if(acl == null) {
		acl = mutableAclService.createAcl(oid);
	}
	acl.insertAce(null, permission, recipient, true);
}

@Override
public void deletePermission(Contact contact, Sid recipient, Permission permission) {
	ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
	MutableAcl acl = (MutableAcl) mutableAclService.readAclById(oid);
	AccessControlEntry[] entries = acl.getEntries();
	for(int i = 0; i < entries.length; i++) {
		if(entries[i].getSid().equals(recipient) && entries[i].getPermission().equals(permission)) {
			acl.deleteAce(entries[i].getId());
		}
	}
	updateAclInTransaction(acl);
}

@Override
public void grantPermission(Long id, String recipientName, Permission permission) {
	MutableAcl acl;
	ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, new Long(id));
	acl = (MutableAcl) mutableAclService.readAclById(oid);
	acl.insertAce(null, permission, new PrincipalSid(recipientName), true);
	updateAclInTransaction(acl);
}

Untuk membuat 5 table baru yg dibutuhkan dari ACL, maka kita membuat class DataSourcePopulator :

  1. ACL_SID : User berhak akses.
  2. ACL_CLASS : dimana class yang akan digunakan.
  3. ACL_OBJECT_IDENTITY : Digunakan untuk memasukkan data class, dan data SID.
  4. ACL_ENTRY : Digunakan untuk memasukkan data permission.

DataSourcePopulator.java

jdbcTemplate.execute("CREATE TABLE ACL_SID(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,PRINCIPAL BOOLEAN NOT NULL,SID VARCHAR_IGNORECASE(100) NOT NULL,CONSTRAINT UNIQUE_UK_1 UNIQUE(SID,PRINCIPAL));");
jdbcTemplate.execute("CREATE TABLE ACL_CLASS(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,CLASS VARCHAR_IGNORECASE(100) NOT NULL,CONSTRAINT UNIQUE_UK_2 UNIQUE(CLASS));");
jdbcTemplate.execute("CREATE TABLE ACL_OBJECT_IDENTITY(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,OBJECT_ID_CLASS BIGINT NOT NULL,OBJECT_ID_IDENTITY BIGINT NOT NULL,PARENT_OBJECT BIGINT,OWNER_SID BIGINT,ENTRIES_INHERITING BOOLEAN NOT NULL,CONSTRAINT UNIQUE_UK_3 UNIQUE(OBJECT_ID_CLASS,OBJECT_ID_IDENTITY),CONSTRAINT FOREIGN_FK_1 FOREIGN KEY(PARENT_OBJECT)REFERENCES ACL_OBJECT_IDENTITY(ID),CONSTRAINT FOREIGN_FK_2 FOREIGN KEY(OBJECT_ID_CLASS)REFERENCES ACL_CLASS(ID),CONSTRAINT FOREIGN_FK_3 FOREIGN KEY(OWNER_SID)REFERENCES ACL_SID(ID));");
jdbcTemplate.execute("CREATE TABLE ACL_ENTRY(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,ACL_OBJECT_IDENTITY BIGINT NOT NULL,ACE_ORDER INT NOT NULL,SID BIGINT NOT NULL,MASK INTEGER NOT NULL,GRANTING BOOLEAN NOT NULL,AUDIT_SUCCESS BOOLEAN NOT NULL,AUDIT_FAILURE BOOLEAN NOT NULL,CONSTRAINT UNIQUE_UK_4 UNIQUE(ACL_OBJECT_IDENTITY,ACE_ORDER),CONSTRAINT FOREIGN_FK_4 FOREIGN KEY(ACL_OBJECT_IDENTITY) REFERENCES ACL_OBJECT_IDENTITY(ID),CONSTRAINT FOREIGN_FK_5 FOREIGN KEY(SID) REFERENCES ACL_SID(ID));");
jdbcTemplate.execute("CREATE TABLE CONTACT(ID BIGINT NOT NULL PRIMARY KEY, NAME VARCHAR_IGNORECASE(100) NOT NULL, ADDRESS VARCHAR_IGNORECASE(200) NOT NULL);");

Jadi kita konfigurasi di appContext-acegi-contact.xml untuk method getAll diberikan role seperti ROLE_USER, ROLE_PERMISSION_LIST :

appContext-acegi-contact.xml

<bean id="afterInvocationManager" class="org.acegisecurity.afterinvocation.AfterInvocationProviderManager">
	<property name="providers">
		<list><ref local="afterAclCollectionRead" /></list>
	</property>
</bean>

<bean id="afterAclCollectionRead" class="org.acegisecurity.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
	<constructor-arg><ref bean="aclService" /></constructor-arg>
	<constructor-arg>
		<list>
			<ref local="org.acegisecurity.acls.domain.BasePermission.ADMINISTRATION" />
			<ref local="org.acegisecurity.acls.domain.BasePermission.READ" />
		</list>
	</constructor-arg>
</bean>

<bean id="contactServiceSecurity" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
	<property name="validateConfigAttributes">
		<value>false</value>
	</property>
	<property name="authenticationManager">
		<ref local="authenticationManager" />
	</property>
	<property name="accessDecisionManager">
		<ref local="accessDecisionManager" />
	</property>
	<property name="afterInvocationManager">
		<ref bean="afterInvocationManager"/>
	</property>
	<property name="objectDefinitionSource">
		<value>
			com.acegi.contact.ContactService.getAll*=ROLE_PERMISSION_LIST,AFTER_ACL_COLLECTION_READ
		</value>
	</property>
</bean>

Yang terakhir, kita membuat class ContactMain untuk menjalankan semua yang di atas.
Ada 2 method untuk melakukan pemanggilan ACL :

  1. method makeActivate : login sedang berjalan di atas aplikasi.
  2. method makeGrantPermission : assign permission memiliki level.

ContactMain.java

private GrantedAuthority[] getAuthorities(String[] roles) {
	GrantedAuthorityImpl[] authorityImpls = new GrantedAuthorityImpl[roles.length];
	for (int i = 0; i < roles.length; i++) {
		authorityImpls[i] = new GrantedAuthorityImpl(roles[i]);
	}
	return authorityImpls;
}

private void makeActivate(String name, String[] roles) {
	destroySecureContext();
	Authentication auth = new UsernamePasswordAuthenticationToken(name,
			"123", getAuthorities(roles));
	SecurityContextHolder.getContext().setAuthentication(auth);
}

private void makeGrantPermission() {
	contactService.grantPermission(new Long(1), "paulus", BasePermission.ADMINISTRATION);
	contactService.grantPermission(new Long(2), "paulus", BasePermission.READ);
	contactService.grantPermission(new Long(3), "paulus", BasePermission.READ);
	contactService.grantPermission(new Long(2), "dhiku", BasePermission.READ);
	contactService.grantPermission(new Long(3), "dhiku", BasePermission.READ);
	contactService.grantPermission(new Long(1), "endy", BasePermission.ADMINISTRATION);
	contactService.grantPermission(new Long(3), "endy", BasePermission.READ);
}

private void listOfContacts() {
	// paulus list of contact
	System.out.println("User : " + getUsername());
	showListOfContact();
	System.out.println("================================");

	// dhiku list of contact
	makeActivate("dhiku", new String[]{"ROLE_PERMISSION_LIST"});
	System.out.println("User : " + getUsername());
	showListOfContact();
	System.out.println("================================");

	// endy list of contact
	makeActivate("endy", new String[]{"ROLE_PERMISSION_LIST"});
	System.out.println("User : " + getUsername());
	showListOfContact();
	System.out.println("================================");

	// blank list of contact
	makeActivate("blank", new String[]{"ROLE_DONT_PERMISSION_LIST"});
	System.out.println("User : " + getUsername());
	showListOfContact();
	System.out.println("================================");

	makeActivate("paulus", new String[]{"ROLE_PERMISSION_LIST"});
	Contact contact = (Contact) contactService.getById(new Long(2));
	contactService.deletePermission(contact, new PrincipalSid("dhiku"), BasePermission.READ);
	System.out.println("After user '" + getUsername() + "' can delete permission for dhiku");
	System.out.println("================================");

	// dhiku list of contact
	makeActivate("dhiku", new String[]{"ROLE_PERMISSION_LIST"});
	System.out.println("User : " + getUsername());
	showListOfContact();
}

Output :

User : paulus
class com.acegi.contact.Contact@paulus#bintaro
class com.acegi.contact.Contact@dhiku#pim
class com.acegi.contact.Contact@endy#cibinong
================================
User : dhiku
class com.acegi.contact.Contact@dhiku#pim
class com.acegi.contact.Contact@endy#cibinong
================================
User : endy
class com.acegi.contact.Contact@paulus#bintaro
class com.acegi.contact.Contact@endy#cibinong
================================
User : blank
User 'blank' access is denied. Hahaha ... kasihan deh lo ..
================================
After user 'paulus' can delete permission for dhiku
================================
User : dhiku
class com.acegi.contact.Contact@endy#cibinong

Semoga tutorial ini bermanfaat bagi Anda. Mudah khan ?😀

Kalian dapat download di sini.


Actions

Information

2 responses

22 05 2009
nyuby

Mantap mas, minta tutorial lengkapnya dunk mas, cos file nya gak ada dilink…

30 06 2009
ismail

paullllll,,.tolongin mail ya,.,.lagi bingung nih ul skripsi mau bikin apaan???????kasih ide dong ul,.,paul kan briian banget,,.,.,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: