2017-12-04 3 views
0

Wenn Spring Data Rest verwendet wird, gibt es eine Möglichkeit, bestimmte Benutzer nur Teile einer Entität mit einer PUT-Anfrage bearbeiten zu lassen?Wie können bestimmte Benutzer daran gehindert werden, alle Attribute eines Objekts mit PUT mit Spring Data Rest zu bearbeiten?

Unter diesen Artikel als Beispiel:

{ 
    "name": "Item1", 
    "description": "Description", 
    "creator": "User1" 
} 

Was ist der beste Weg, der Schöpfer des Elements bearbeiten das gesamte Element mit einer PUT-Anforderung zu lassen, während andere Benutzer zu beschränken nur die „Beschreibung“ Feld bearbeiten?

Ich habe versucht, einen benutzerdefinierten Validator und einen Ereignishandler ohne Glück zu verwenden.

+0

Haben Sie REST-Repository-Ereignisse ausprobiert? Wie in @HandleBeforeSave Ereignisse und solche? –

+0

Ja, das Problem besteht darin, dass das Element, das an den Handler übergeben wird, bereits so geändert wurde, dass es über die PUT-Anforderung übergeben wurde. – Florian

+0

Und ist es möglich, die Änderung in der Datenbankschicht behandeln (z. B. wenn mysql Einstellung updateable = false)? –

Antwort

1

Ich denke, dass benutzerdefinierte Validator die richtige Wahl in Ihrem Fall ist.

Erste - Ihr Unternehmen aktualisieren, um sie den vorherigen Zustand zu machen Speichern (dank @AlanHay):

@Entity 
class ItemEntity { 

    @Transient 
    private ItemEntity previousState; 

    @PostLoad 
    private void setPreviousState(){ 
     previousState = new ItemEntity(); 
     //copy the fields 
    } 

    public ItemEntity getPreviousState(){ 
     return previousState; 
    } 
} 

Dann Validator implementieren, in dem Sie überprüfen, ob der aktuelle Benutzer mit einigen ‚Behörde‘ die Felder geändert hat:

public class ItemValidator implements Validator { 

    @Override 
    public boolean supports(Class<?> clazz) { 
     //... 
    } 

    @Override 
    public void validate(Object target, Errors errors) { 

     Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities(); 
     SimpleGrantedAuthority userRole = new SimpleGrantedAuthority("ROLE_USER"); 

     if (authorities.contains(userRole)) { 

      ItemEntity item = (ItemEntity) target; 
      prevItem = item.getPreviousState(); 

      String prevName = prevItem.getName(); 
      String prevCreator = prevItem.getCreator(); 
      String newName = item.getName(); 
      String newCreator = item.getCreator(); 

      if (!prevName.equals(newName)) { 
       errors.rejectValue("name", "You cannot change Name field!"); 
      } 

      if (!prevCreator.equals(newCreator)) { 
       errors.rejectValue("creator", "You cannot change Creator field!"); 
      } 
     } 
     // Other checks... 
    } 
} 

Dann in RepositoryRestConfigurerAdapter Stecker dieser Validator:

@Configuration 
public class RepoRestConfig extends RepositoryRestConfigurerAdapter { 

    @Override 
    public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) { 
     v.addValidator("beforeCreate", itemValidator()); // POST (if needed) 
     v.addValidator("beforeSave", itemValidator()); // PUT/PATCH 
     super.configureValidatingRepositoryEventListener(v); 
    } 

    @Bean 
    ListingValidator itemValidator() { 
     return new ItemValidator(); 
    } 
} 

Ich denke, das sollte funktionieren ...

Verwandte Themen