gradle project:
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation group:'com.github.jferrater', name: 'opa-datafilter-mongo-spring-boot-starter', version: '0.5.1'or maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>com.github.jferrater</groupId>
<artifactId>opa-datafilter-mongo-spring-boot-starter</artifactId>
<version>0.5.1</version>
</dependency>- Add the following minimum configuration to the application.yml or application.properties of the Spring Boot project. Replace the values as necessary. See
Configurationssection for more details.
opa:
authorization:
url: "http://localhost:8181/v1/compile"
partial-request:
query: "data.petclinic.authz.allow = true"
unknowns:
- "data.pets"
# Spring Data MongoDB specific configurations
spring:
data:
mongodb:
database: user_service
uri: "mongodb://mongo:mongo@mongo-database:27017/user_service"- Create a sub interface of
OpaDataFilterMongoRepository. This repository is a sub-interface of Spring Data MongoDB repository which overrides thefindAll()method to enforce authorization. ThefindAll()method sends a partial request to the OPA server. The response from OPA which is a simplified version of the policy is translated intoQueryobject which will be used by Spring Data MongoDB to filter results. The filtered results are the data the user is allowed to see.
package com.github.jferrater.userservice.repository;
import com.github.jferrater.opadatafiltermongospringbootstarter.repository.OpaDataFilterMongoRepository;
import com.github.jferrater.userservice.repository.document.User;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserRepository extends OpaDataFilterMongoRepository<User, String> {
List<User> findByOrganizationAndUsername(String organization, String username);
}where the document object:
package com.github.jferrater.userservice.repository.document;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "users")
public class User {
@Id
private String id;
@Indexed
private String organization;
@Indexed(unique = true)
private String username;
private String password;
private String[] roles;
private String[] permissions;
//getters & setters
}- Finally, enable MongoDB repository. Note that
repositoryFactoryBeanClass = OpaMongoRepositoryFactoryBean.classis required in the@EnableMongoRepositories.
package com.github.jferrater.userservice.config;
import com.github.jferrater.opadatafiltermongospringbootstarter.repository.OpaMongoRepositoryFactoryBean;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@Configuration
@EnableMongoRepositories(
basePackages = "com.github.jferrater.userservice.repository"
, repositoryFactoryBeanClass = OpaMongoRepositoryFactoryBean.class
)
public class MongoDbConfig {
@Value("${spring.data.mongodb.uri}")
private String connectionUrl;
@Value("${spring.data.mongodb.database}")
private String databaseName;
@Bean
public MongoClient mongo() {
return MongoClients.create(connectionUrl);
}
@Bean
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongo(), databaseName);
}
}See example Spring Boot microservice applicatio that use the library: