2015-11-11 7 views
8

In einer Anwendung mit Spring Data JPA und Spring Data REST, sagen wir mal Sie eine Entität Klasse wie dieses:Wie kann der Zugriff nach Rolle auf eine Spring Data REST-Projektion beschränkt werden?

@Entity 
public class Person { 

    @Id @GeneratedValue 
    private int id; 

    private String name; 

    @JsonIgnore 
    private String superSecretValue; 

    ... 

} 

Wir wollen Spring Data REST alle dies Unternehmens Felder außer für superSecretValue, entlarven und so wir habe dieses Feld mit @JsonIgnore kommentiert.

jedoch in einigen Fällen wir tun Zugang zu superSecretValue wollen und so schaffen wir einen Vorsprung auf, der alle Felder einschließlich eines zurück:

@Projection(name = "withSecret", types = {Person.class}) 
public interface PersonWithSecret { 

    String getName(); 
    String getSuperSecretValue(); 

} 

ehrfürchtig. So, jetzt können wir Person Einheiten zugreifen einschließlich der superSecretValue Feld wie folgt aus:

curl http://localhost:8080/persons?projection=withSecret 

Meine Frage ist wie können wir sicher, dass Vorsprung? Wie können wir Dinge so konfigurieren, dass jeder Person Entitäten ohne das Feld superSecretValue abrufen kann ... aber nur Leute mit einer bestimmten Rolle (zB ROLE_ADMIN) können die Projektion verwenden, um das versteckte Feld abzurufen?

Ich habe endlose Beispiele für die Verwendung @PreAuthorize oder @Secured Anmerkungen gefunden Spring Data JPA-Repository CRUD Methoden zu sichern (z save(), delete()) ... aber keine Beispiele dafür, wie Verwendung eines Spring Data REST Projektion zu beschränken.

+0

Die Frage vor gefragt wurde - http://stackoverflow.com/questions/28794145/spring-data-rest-security-based-projection - ich glaube, Was Sie versuchen zu tun, wird nicht unterstützt. Ich würde auch fragen, ob Sie es tun sollten - eine Projektion ist nur eine andere Sicht auf die Daten und das Einbringen von Sicherheit hier klingt nicht richtig. Ich würde gehen und implementieren Sie eine benutzerdefinierte Controller-Methode für diese und sichern Sie diese. –

+0

@MathiasDpunkt: Angenommen, Sie haben eine benutzerdefinierte Controller-Methode mit dem Rückgabetyp "Person" geschrieben und die Annotation "@ ResponseBody" angewendet, um sie in JSON zu serialisieren. In diesem Fall wird das Feld 'superSecretValue' aufgrund der Annotation '@ JsonIgnore' weiterhin weggelassen. Würden Sie die Entität "Person" manuell in eine im Wesentlichen identische DTO-Klasse umwandeln, ohne dass "@ JsonIgnore" in diesem Feld angezeigt wird? Würden Sie Ihren eigenen benutzerdefinierten Jackson-Serializer implementieren und den JSON selbst erstellen, anstatt sich auf '@ ResponseBody' zu verlassen? Ein anderer Ansatz? –

+2

@MathiasDpunkt: Es scheint, als wäre es ein nicht zu ungewöhnlicher Anwendungsfall, um rollenbasierte Sichtbarkeit in bestimmten Bereichen zu benötigen. Das Gewähren von rollenbasiertem Zugriff auf Repository-CRUD-Methoden ist so einfach, dass es ziemlich umständlich ist, die rollenbasierte Sichtbarkeit von Entitätsfeldern so schwerfällig zu machen. Ich versuche nur den Weg des geringsten Widerstands zu finden. –

Antwort

1

Sie können Eigenschaften in Projektionen mit @Value mit bedingten SpEL-Ausdrücke überladen - wie in diesem already answered similar question.

Betrachten wir andere Alternativen (andere bereits erwähnt):

  1. Modell Refactoring. Geteilte Entität durch Zugriffslogik (z. B. Person < ->Account)
  2. Hinzufügen benutzerdefinierter Endpunkte für spezielle Logik- und Zugriffsprüfungen. Zum Beispiel der aktuelle Benutzer bei "/ people/me".
  3. Anpassen von Standardendpunkten. Fügen Sie beispielsweise einen benutzerdefinierten Controller für "/ people", "/ people/{id}" hinzu, der den benutzerdefinierten Typ Resource (DTO) entsprechend den Benutzerberechtigungen vorverarbeitet und zurückgibt (z. B. PublicPerson statt Person). Dann können Sie benutzerdefinierte Ressourcenprozessoren zum Hinzufügen von benutzerdefinierten Links und benutzerdefinierten Projektionen für diese Typen schreiben.

Siehe auch: Ausgabe zu diesem Thema ab Frühjahr-data-Rest DATAREST-428.

0

Sie diese Lösung versuchen könnte: https://stackoverflow.com/a/35399030/679240

@Projection(name = "detailed", types = User.class) 
public interface UserDetailProjection extends UserSimpleProjection{ 

    @Value("#{@userService.checkAccess(target)? target.email : null}") 
    public String getEmail(); 
} 
Verwandte Themen