Blog

Understanding Spring Security – Part 4 – ACL Security

by | Jul 30, 2012 | Content Security, Webapps | 0 comments

Spring Security also provides domain object level security in addition to the other types of security discussed in this Spring Security blog series. In simple terms, ACL provides a way to specify permissions based on a combination of role, business object (referred to as domain object) and permissions. For example, if you want to grant a user read permission based on their role, on their own user data, you would use ACL security.

Spring Security’s ACL services are shipped in the spring-security-acl-xxx.jar. You will need to add this JAR to your classpath to use Spring Security’s domain object instance security capabilities.

Spring Security’s domain object instance security capabilities centre on the concept of an access control list (ACL). Every domain object instance in your system has its own ACL, and the ACL records details of who can and can’t work with that domain object.

In order to secure various domain objects, you must create ACL Tables. I have provided the SQL for creating ACL Tables here:

create database acl;

use acl;

CREATE TABLE IF NOT EXISTS `acl_sid` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,

  `principal` tinyint(1) NOT NULL,

  `sid` varchar(100) NOT NULL,

  PRIMARY KEY (`id`),

  UNIQUE KEY `unique_uk_1` (`sid`,`principal`)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

CREATE TABLE IF NOT EXISTS `acl_class` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,

  `class` varchar(255) NOT NULL,

  PRIMARY KEY (`id`),

  UNIQUE KEY `unique_uk_2` (`class`)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

CREATE TABLE IF NOT EXISTS `acl_entry` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,

  `acl_object_identity` bigint(20) NOT NULL,

  `ace_order` int(11) NOT NULL,

  `sid` bigint(20) NOT NULL,

  `mask` int(11) NOT NULL,

  `granting` tinyint(1) NOT NULL,

  `audit_success` tinyint(1) NOT NULL,

  `audit_failure` tinyint(1) NOT NULL,

  PRIMARY KEY (`id`),

  UNIQUE KEY `unique_uk_4` (`acl_object_identity`,`ace_order`),

  KEY `foreign_fk_5` (`sid`)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=43 ;

CREATE TABLE IF NOT EXISTS `acl_object_identity` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,

  `object_id_class` bigint(20) NOT NULL,

  `object_id_identity` bigint(20) NOT NULL,

  `parent_object` bigint(20) DEFAULT NULL,

  `owner_sid` bigint(20) DEFAULT NULL,

  `entries_inheriting` tinyint(1) NOT NULL,

  PRIMARY KEY (`id`),

  UNIQUE KEY `unique_uk_3` (`object_id_class`,`object_id_identity`),

  KEY `foreign_fk_1` (`parent_object`),

  KEY `foreign_fk_3` (`owner_sid`)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;

ALTER TABLE `acl_entry`

  ADD CONSTRAINT `foreign_fk_4` FOREIGN KEY (`acl_object_identity`) REFERENCES `acl_object_identity` (`id`),

  ADD CONSTRAINT `foreign_fk_5` FOREIGN KEY (`sid`) REFERENCES `acl_sid` (`id`);

ALTER TABLE `acl_object_identity`

  ADD CONSTRAINT `foreign_fk_1` FOREIGN KEY (`parent_object`) REFERENCES `acl_object_identity` (`id`),

  ADD CONSTRAINT `foreign_fk_2` FOREIGN KEY (`object_id_class`) REFERENCES `acl_class` (`id`),

  ADD CONSTRAINT `foreign_fk_3` FOREIGN KEY (`owner_sid`) REFERENCES `acl_sid` (`id`);

 

Once this is completed, the following tables need to be created:

A datasource is created and injected into a JdbcMutableAclService and BasicLookupStrategy instance.  BasicLookupStrategy does the lookup of the acl. The domain objects that we want to secure should have a public Serializable getId() method that returns a type long or compatible with long.

 

Next step is to create a AccessDecisionVoter or AfterInvocationProvider that would use AclService’s isGranted() method to retrieve the ACL and check whether the permission is granted or not.

Categories

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *