Sto tentando di implementare il controllo dell'accesso a grana fine sfruttando ancora il riposo dati Spring.Controllo accesso repository in Spring Data Rest basato su utente princpal
Sto lavorando per rendere sicuro un CrudRepository
in modo che gli utenti possano modificare o inserire solo i dati che appartengono a loro. Sto facendo uso di @PreAuthorize
/@PostAuthorize
e @PreFilter
/@PostFilter
per bloccare l'accesso al principale corrente.
Finora il mio repository appare così.
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();
}
Mentre questo è un po 'noioso, sembra realizzare ciò che sto cercando. (Se qualcuno conosce un modo migliore, non esitate a farmi sapere!)
Dove sto correndo in problemi è con delete()
, count()
e exists()
@Override
long count();
@Override
void delete(Integer integer);
@Override
void delete(MyObject entity);
@Override
void deleteAll();
@Override
boolean exists(Integer integer);
Questi metodi prendere un parametro Integer
ID o proprio nessuno. Sembra che dovrei prima selezionare l'entità con l'ID di input e quindi eseguire il controllo di autenticazione.
Questo tipo di autorizzazione è possibile all'interno del repository?
Grazie
Edit:
Grazie a ksokol questo sembra funzionare ora.
ho aggiunto un nuovo bean a una classe di @Configuration
@Bean
public EvaluationContextExtension securityExtension() {
return new SecurityEvaluationContextExtensionImpl();
}
Questo bean estende EvaluationContextExtensionSupport
e sovrascrive getRootObject
per restituire un SecurityExpressionRoot
che tiene il mio principale personalizzato.
public class SecurityEvaluationContextExtensionImpl extends EvaluationContextExtensionSupport {
@Override
public String getExtensionId() {
return "security";
}
@Override
public Object getRootObject() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return new SecurityExpressionRoot(authentication){};
}
}
Grazie ksokol, queste query JPQL sovrascriveranno il comportamento implementato di runtime predefinito? Come stai riferendo i parametri del metodo, stai usando? 1 – francis
Sì. Sostituiscono le query generate dal runtime. Usando '?1' ecc. Stai facendo riferimento ai parametri del metodo all'interno delle tue query. Vedi [Uso di @Query] (http://docs.spring.io/spring-data/jpa/docs/1.8.0.RELEASE/reference/html/#jpa.query-methods.at-query) per ulteriori informazioni. –