Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating to Spring 5 #6

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 9 additions & 199 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,227 +68,37 @@ This Spring Security ACL customization uses MongoDB as a database to look up acc

This implementation will read (or write) such documents as `MongoAcl` objects from (and to) the MongoDB and map the POJO to respective Spring Security ACL classes such as `Acl`, `Sid`, `ObjectIdentity` and/or `AccessControlEntry` instances. As the customized `AclService`/`MutableAclService` returns `Acl` instances replacing the SQL based ACL with the MongoDB based ACL code should be trivial.

# Configuration

Before being able to use Spring Security ACL MongoDB it has to be defined as dependency and configured properly in order to work.

## Dependency Management
## Installation

### Maven

In order to make use of the MongoDB based ACL one has to declare its dependency in Maven like below:
This package is not on any remote repository, so the build and install of the package is needed: `mvn clean install`

```xml
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-acl-mongodb</artifactId>
<version>4.2.3-SNAPSHOT</version>
<version>5.3.6-SNAPSHOT</version>
</dependency>
```

Note that the artifacts are not yet available on Maven Central. So please build the project manually via `mvn clean install` first before declaring the dependencies on this artifact.

### Gradle

Via Gradle the dependency can be added by simply adding the following line to the .gradle file:

```groovy
compile "org.springframework.security:spring-security-acl-mongodb:4.2.3-SNAPSHOT"
compile "org.springframework.security:spring-security-acl-mongodb:5.3.6-SNAPSHOT"
```

Note that the artifacts are not yet available on Maven Central (or similar repositories). Hence build the project manually first before declaring the dependencies on this artifact.

### XML based configuration

After the dependencies are available one must define a `MongoTemplate` as well as `MongoRepository` bean via Spring.

On using XML based configuration a sample configuration can look like below

```xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
">

<!-- MongoDB used for the ACL management -->

<!-- declaring a mongo client that way did not work on my site hence the manual configuration below -->
<!--<mongo:mongo id="mongo" host="localhost" port="27017"/>-->
<!--<mongo:db-factory id="mongoDbFactory" dbname="spring-security-acl-test" mongo-ref="mongo"/>-->

<bean id="mongo" class="com.mongodb.MongoClient">
<constructor-arg name="host" value="localhost"/>
<constructor-arg name="port" value="27017"/>
</bean>

<bean id="mongoDbFactory" class="org.springframework.data.mongodb.core.SimpleMongoDbFactory">
<constructor-arg name="mongoClient" ref="mongo"/>
<constructor-arg name="databaseName" value="spring-security-acl"/>
</bean>

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongoDbFactory" />
</bean>

<!-- Handle MongoExceptions caught in @Repository annotated classes -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

<!-- Make the aclRepository bean instance available to inject -->
<context:annotation-config />
<context:component-scan base-package="org.springframework.security.acls" />

<!-- The Spring-Data-MongoDB Acl repository -->
<mongo:repositories base-package="org.springframework.security.acls.dao"/>
</beans>
```

The database name is optional. In contrast to the SQL ACL implementation no predefined table definitions are necessary.

Once the Mongo client is available and the template as well as the repository are in place the `AclService` implementation has to be configured. The `MongoDBMutableAclService` implementation provides, in contrast to the `MongoDBAclService` implementation, which supports ACL entry lookups, full CRUD functionality on ACL entries.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- ========= ACL SERVICE DEFINITIONS ========= -->
## Configuration

<bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
<constructor-arg>
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
</property>
<property name="cacheName" value="aclCache"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy">
<constructor-arg>
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
</constructor-arg>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<constructor-arg>
<list>
<bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
<constructor-arg value="ROLE_ACL_ADMIN"/>
</bean>
</list>
</constructor-arg>
</bean>
</constructor-arg>
</bean>

<bean id="lookupStrategy" class="org.springframework.security.acls.mongodb.BasicLookupStrategy">
<constructor-arg ref="mongoTemplate"/>
<constructor-arg ref="aclCache"/>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<constructor-arg>
<bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
<constructor-arg value="ROLE_ADMINISTRATOR"/>
</bean>
</constructor-arg>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
</constructor-arg>
</bean>

<bean id="aclService" class="org.springframework.security.acls.mongodb.MongoDBMutableAclService">
<constructor-arg ref="lookupStrategy"/>
<constructor-arg ref="aclCache"/>
</bean>

</beans>
```

The `aclService` can then be used to inject an instance into some business logic classes as depicted below:

```xml
<!-- The business class implementing the actual logic -->

<bean id="contactManager" class="sample.contact.ContactManagerBackend">
<property name="contactDao">
<bean class="sample.contact.ContactDaoSpring">
<property name="dataSource" ref="dataSource"/>
</bean>
</property>
<property name="mutableAclService" ref="aclService"/>
</bean>
```

### Java based configuration

The configuration via Java configuration isn't that differnt from the XML based configuration.
Tell your application to read the beans:

```java
@Configuration
@EnableMongoRepositories(basePackageClasses = {AclRepository.class })
public class ContextConfig {

@Bean
public MongoTemplate mongoTemplate() throws UnknownHostException
{
MongoClient mongoClient = new MongoClient("localhost", 27017);
return new MongoTemplate(mongoClient, "spring-security-acl-test");
}

@Bean
public AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMINISTRATOR"));
}

@Bean
public PermissionGrantingStrategy permissionGrantingStrategy() {
ConsoleAuditLogger consoleAuditLogger = new ConsoleAuditLogger();
return new DefaultPermissionGrantingStrategy(consoleAuditLogger);
}

@Bean
public LookupStrategy lookupStrategy() throws UnknownHostException {
return new BasicLookupStrategy(mongoTemplate(), aclCache(), aclAuthorizationStrategy(), permissionGrantingStrategy());
}

@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("test");
}

@Bean
public AclCache aclCache() {
Cache springCache = cacheManager().getCache("test");
return new SpringCacheBasedAclCache(springCache, permissionGrantingStrategy(), aclAuthorizationStrategy());
}

@Bean
public AclService aclService() throws UnknownHostException {
return new MongoDBMutableAclService(lookupStrategy(), aclCache());
}
}
@SpringBootApplication(scanBasePackages = {"com.your.app", "org.springframework.security.acls"})
```

As usual both `AclRepository` and `MongoDBMutableAclService` can be injected using either `@Autowired`, `@Resource` or `@Inject` annotations

```java
@Resource
private MongoDBMutableAclService aclService;
@Resource
private AclRepository aclRepository;
```
> Been looking to autoconfigure the package without this without luck, help needed :smiley_face:

# Usage
## Usage

AS this implementation maps the MongoDB documents to `AclImpl` instances used by Spring Security ACL, evaluating user permissions on accessing domain objects should be straight forward via standard `@PreAuthorize`, `@PostAuthorize`, `@PreFilter` and `@PostFilter` Spring Security annotations which get evaluated by `AclPermissionEvaluator` by default.

Expand Down
Loading