Repository-Zugriffskontrolle in Spring Data Rest basierend auf Benutzer princpal

Ich versuche, eine feinkörnige Zugriffskontrolle zu implementieren, während ich die Vorteile von Spring Data Rest ausnütze.

Ich arbeite daran, ein @ zu sicheCrudRepository Benutzer können nur die Daten ändern oder einfügen, die ihnen gehören. Ich benutze@PreAuthorize/@PostAuthorize und@PreFilter/@PostFilter, um den Zugriff auf den aktuellen Principal zu sperren.

So weit sieht mein Repository so aus.

public interface MyRepository extends CrudRepository<MyObject, Integer> {

    @PreAuthorize("#entity.userId == principal.id")
    @Override
    <S extends MyObject> S save(S entity);

    @PreFilter("filterObject.userId === principal.id")
    @Override
    <S extends MyObject> Iterable<S> save(Iterable<S> entities);

    @PostAuthorize("returnObject.userId == principal.id")
    @Override
    MyObject findOne(Integer integer);

    @PostFilter("filterObject.userId == principal.id")
    @Override
    Iterable<MyObject> findAll();

}

Während dies ein bisschen langweilig ist, scheint es das zu erreichen, wonach ich suche. (Wenn jemand einen besseren Weg kennt, lass es mich gerne wissen!)

Wo ich auf Probleme stoße ist mitdelete(), count() undexists()

    @Override
    long count();

    @Override
    void delete(Integer integer);

    @Override
    void delete(MyObject entity);

    @Override
    void deleteAll();

    @Override
    boolean exists(Integer integer);

Diese Methoden nehmen entweder einInteger ID-Parameter oder gar keiner. Es scheint, als müsste ich zuerst die Entität mit der Eingabe-ID auswählen und dann die Authentifizierungsprüfung durchführen.

Ist diese Art der Autorisierung im Repository möglich?

Vielen Dan

Bearbeiten

Danke an ksokol, das scheint jetzt zu funktionieren.

Ich habe eine neue Bean zu einem @ hinzugefü@Configuration class

@Bean
public EvaluationContextExtension securityExtension() {
    return new SecurityEvaluationContextExtensionImpl();
}

Diese Bohne verlängertEvaluationContextExtensionSupport und überschreibtgetRootObject um ein @ zurückzugebSecurityExpressionRoot das hält mein benutzerdefiniertes Prinzipal.

public class SecurityEvaluationContextExtensionImpl extends EvaluationContextExtensionSupport {
@Override
public String getExtensionId() {
    return "security";
}

@Override
public Object getRootObject() {
        Authentication authentication =   SecurityContextHolder.getContext().getAuthentication();
        return new SecurityExpressionRoot(authentication){};
    }
}

Antworten auf die Frage(4)

Ihre Antwort auf die Frage