Hi there.
Summary
I want to perform a @PreAuthorize on a MongoRepository where the owner of the entity is stored in a field of the entity.
import lombok.Data;
import org.springframework.data.annotation.Id;
public @Data class Event {
@Id
private String id;
private String title;
private String username; // HERE
private String date;
private String location;
}
So I create a Repository like this (inspired by many tutorial)
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
@RepositoryRestResource(collectionResourceRel = "event", path = "event")
@Secured("ROLE_user")
public interface EventRepository extends MongoRepository<Event, String> {
/** Only owner can save the Event */
@Override
@PreAuthorize("#entity.username.equals(authentication.name)")
<S extends Event> S save(S entity);
}
With this code I can make an abstract and all my save will implament same PreAuthorize with same effect.
But it's not secure for me, if user toto know api and send all Event and changing field username by toto he will able to change all event and gone owner of all events.
So I changed my code:
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
@RepositoryRestResource(collectionResourceRel = "event", path = "event")
@Secured("ROLE_user")
public interface EventRepository extends MongoRepository<Event, String> {
/** Only owner can save the Event */
@Override
@PreAuthorize("#entity.id == null OR @eventRepository.findById(#entity.id).get().getUsername().equals(authentication.name)")
<S extends Event> S save(S entity);
}
That do the job but I can't abstract this PreAuthorize, cause eventRepository.
So I have to change/set it on all save methods for all my Repository which work like this one.
I miss a magic keyword to point to the current repository in SpEL? It's the best way to check that?
Actual Behavior
Can't abstract a same PreAuthorize Crud Repository
Expected Behavior
Find a way to abstract a same PreAuthorize Crud Repository :)
Configuration
Only Usefull config
....
@EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
...
Version
plugins {
id "java"
id "idea"
id "org.springframework.boot" version '2.1.8.RELEASE'
}
...
apply plugin: 'io.spring.dependency-management'
...
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-data-rest")
compile("org.springframework.boot:spring-boot-starter-data-mongodb")
compile("org.springframework.boot:spring-boot-starter-security")
...
Sample
Want to do something like:
public @Data
class AbstractOwnerData {
@Id
private String id;
private String username;
}
@EqualsAndHashCode(callSuper = true)
public @Data class Event extends AbstractOwnerData{
private String title;
private String date;
private String location;
}
public interface AbstractOwnerDataRepository<T extends AbstractOwnerData> extends MongoRepository<T, String> {
@Override
@PreAuthorize("#entity.id == null OR @currentRepository.findById(#entity.id).get().getUsername().equals(authentication.name)")
<S extends T> S save(S entity);
}
@RepositoryRestResource(collectionResourceRel = "event", path = "event")
@Secured("ROLE_user")
public interface EventRepository extends AbstractOwnerDataRepository<Event> {
// nothing
}
@RepositoryRestResource(collectionResourceRel = "xxxx", path = "xxxx")
@Secured("ROLE_user")
public interface XxxxRepository extends AbstractOwnerDataRepository<Xxxx> {
// nothing
}
....
I see PermissionResolver but for me make a big switch with all objects class isn't a sexy way to do that.
So any idea?
Comment From: jzheaux
Thanks for getting in touch! It feels like this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that people can find it).