Skip to content

Commit d95ed26

Browse files
Thomas Darimontodrotbohm
authored andcommitted
spring-projects#107 - Added example for Spring Security Integration in MongoDB.
Initial project and with example for dynamic data filtering based on current security context information. Relies on DATAMONGO-1244 to be resolved. Original pull request: spring-projects#108.
1 parent cc6e232 commit d95ed26

File tree

8 files changed

+263
-0
lines changed

8 files changed

+263
-0
lines changed

mongodb/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<module>example</module>
2222
<module>text-search</module>
2323
<module>java8</module>
24+
<module>security</module>
2425
<module>util</module>
2526
<module>geo-json</module>
2627
</modules>

mongodb/security/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Spring Data MongoDB - Spring Security integration.
2+
3+
This project contains samples of the Spring Security integration in Spring Data (MongoDB).
4+
5+
## Support for SpEL Expression based filtering
6+
7+
```java
8+
public interface PersonRepository extends CrudRepository<Person, String> {
9+
10+
@Override
11+
List<Person> findAll();
12+
13+
//Custom Query method with filtering based on Spring Security context information
14+
@Query("{id: ?#{ hasRole('ROLE_ADMIN') ? {$exists:true} : principal.id}}")
15+
List<Person> findAllForCurrentUserById();
16+
}
17+
```
18+

mongodb/security/pom.xml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>org.springframework.data.examples</groupId>
7+
<artifactId>spring-data-mongodb-examples</artifactId>
8+
<version>1.0.0.BUILD-SNAPSHOT</version>
9+
</parent>
10+
11+
<artifactId>spring-data-mongodb-security</artifactId>
12+
<name>Spring Data MongoDB - Spring Security Integration</name>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>${project.groupId}</groupId>
17+
<artifactId>spring-data-mongodb-utils</artifactId>
18+
<version>${project.version}</version>
19+
<scope>test</scope>
20+
</dependency>
21+
22+
<dependency>
23+
<groupId>org.springframework.data</groupId>
24+
<artifactId>spring-data-mongodb</artifactId>
25+
<version>1.8.0.DATAMONGO-1244-SNAPSHOT</version>
26+
</dependency>
27+
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-starter-security</artifactId>
31+
</dependency>
32+
33+
<dependency>
34+
<groupId>org.springframework.security</groupId>
35+
<artifactId>spring-security-data</artifactId>
36+
</dependency>
37+
</dependencies>
38+
39+
</project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.people;
17+
18+
import org.springframework.boot.autoconfigure.SpringBootApplication;
19+
import org.springframework.context.annotation.Bean;
20+
import org.springframework.data.mongodb.core.mapping.event.LoggingEventListener;
21+
import org.springframework.data.repository.query.spi.EvaluationContextExtension;
22+
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
23+
24+
/**
25+
* Simple configuration that registers a {@link LoggingEventListener} to demonstrate mapping behaviour when Java 8
26+
* Streams are used.
27+
*
28+
* @author Thomas Darimont
29+
*/
30+
@SpringBootApplication
31+
class ApplicationConfiguration {
32+
33+
public @Bean LoggingEventListener mongoEventListener() {
34+
return new LoggingEventListener();
35+
}
36+
37+
@Bean
38+
public EvaluationContextExtension securityExtension() {
39+
return new SecurityEvaluationContextExtension();
40+
}
41+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.people;
17+
18+
import lombok.Data;
19+
import lombok.RequiredArgsConstructor;
20+
21+
import org.springframework.data.annotation.Id;
22+
23+
/**
24+
* An entity to represent a Person.
25+
*
26+
* @author Thomas Darimont
27+
*/
28+
@Data
29+
@RequiredArgsConstructor
30+
public class Person {
31+
32+
private @Id String id;
33+
private final String firstname;
34+
private final String lastname;
35+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.people;
17+
18+
import java.util.List;
19+
20+
import org.springframework.data.mongodb.repository.Query;
21+
import org.springframework.data.repository.CrudRepository;
22+
23+
/**
24+
* Repository interface to manage {@link Person} instances.
25+
*
26+
* @author Thomas Darimont
27+
*/
28+
public interface PersonRepository extends CrudRepository<Person, String> {
29+
30+
List<Person> findAll();
31+
32+
@Query("{id: ?#{ hasRole('ROLE_ADMIN') ? {$exists:true} : principal.id}}")
33+
List<Person> findAllForCurrentUserById();
34+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.people;
17+
18+
import static org.hamcrest.CoreMatchers.*;
19+
import static org.junit.Assert.*;
20+
import static org.hamcrest.Matchers.*;
21+
22+
import java.util.Collections;
23+
import java.util.List;
24+
25+
import org.junit.Before;
26+
import org.junit.ClassRule;
27+
import org.junit.Test;
28+
import org.junit.runner.RunWith;
29+
import org.springframework.beans.factory.annotation.Autowired;
30+
import org.springframework.boot.test.SpringApplicationConfiguration;
31+
import org.springframework.data.mongodb.core.MongoOperations;
32+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
33+
import org.springframework.security.core.authority.SimpleGrantedAuthority;
34+
import org.springframework.security.core.context.SecurityContextHolder;
35+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
36+
37+
import example.springdata.mongodb.util.RequiresMongoDB;
38+
39+
/**
40+
* Integration test for {@link PersonRepository}.
41+
*
42+
* @author Thomas Darimont
43+
* @authot Oliver Gierke
44+
*/
45+
@RunWith(SpringJUnit4ClassRunner.class)
46+
@SpringApplicationConfiguration(classes = ApplicationConfiguration.class)
47+
public class PersonRepositoryIntegrationTest {
48+
49+
@ClassRule public static RequiresMongoDB mongodbAvailable = RequiresMongoDB.anyVersion();
50+
51+
@Autowired PersonRepository repository;
52+
@Autowired MongoOperations operations;
53+
54+
Person dave, oliver, carter, admin;
55+
56+
@Before
57+
public void setUp() {
58+
59+
repository.deleteAll();
60+
61+
admin = repository.save(new Person("Admin", "Boss"));
62+
dave = repository.save(new Person("Dave", "Matthews"));
63+
oliver = repository.save(new Person("Oliver August", "Matthews"));
64+
carter = repository.save(new Person("Carter", "Beauford"));
65+
}
66+
67+
@Test
68+
public void nonAdminCallingShouldReturnOnlyItSelfAsPerson() throws Exception {
69+
70+
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(dave, "x"));
71+
72+
List<Person> persons = repository.findAllForCurrentUserById();
73+
74+
assertThat(persons, hasSize(1));
75+
assertThat(persons, contains(dave));
76+
}
77+
78+
@Test
79+
public void adminCallingShouldReturnAllUsers() throws Exception {
80+
81+
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(admin, "x",
82+
Collections.singleton(new SimpleGrantedAuthority("ROLE_ADMIN")));
83+
SecurityContextHolder.getContext().setAuthentication(auth);
84+
85+
List<Person> persons = repository.findAllForCurrentUserById();
86+
87+
assertThat(persons, hasSize(4));
88+
assertThat(persons, containsInAnyOrder(admin, dave, carter, oliver));
89+
}
90+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* Package showing usage of Spring Data MongoDB Repositories with Java 8.
3+
*/
4+
package example.springdata.mongodb.people;
5+

0 commit comments

Comments
 (0)