lunes, 16 de octubre de 2017

How to define repository ownership in JPA with Spring Security?

Hi, everybody!

Today I'm going to explain how to define repository ownership in JPA with Spring Security.

First of all, we are going to explain what is a repository: is an interface of JPA that provide the access to a database table modeled with hibernate.

In this interface, you can define any JPA or native query and you can change the behaivour of any call.

For example, you can have this:

@Repository
public interface MyHibernateModelClassRepository extends JpaRepository<MyHibernateModelClass, Long> {

}


With this implementation, you can call any CRUD method.

Now, I'm going to explain how to define ownership of this JPA interface:

With the same example, you can have this:

@Repository
public interface MyHibernateModelClassRepository extends JpaRepository<MyHibernateModelClass, Long> {

    @PreAuthorize("#entity == null || #entity.id == principal.id")
    @Override
    <S extends MyHibernateModelClass> S save(S entity);

    @PreFilter("filterObject == null || filterObject.id== principal.id")

    @Override
    <S extends MyHibernateModelClass> List<S> save(Iterable<S> entities);

    @PostAuthorize("returnObject.id == principal.id")

    @Override
    MyHibernateModelClass findOne(Long integer);

    @PostFilter("filterObject.id == principal.id")

    @Override
    List<MyHibernateModelClass> findAll();
    
}

With this call, you implemented a JPA interface with ownership, where the CRUD calls can only be used by the user logged in the application is the same of the attribute id in the database table modeled with Hibernate MyHibernateModelClass.

I'm going to provide another example, which use a method of the hibernate entity that response with a boolean if the CRUD method can be use by this user.

Here is the next example:

(hibernate entity have this method):
...
public boolean hasMetadadaWithId(Long id) {
return (metadades.getId().equals(id));
}
...

And the JPA repository shows like this:

@Repository
public interface MyHibernateModelClassRepository extends JpaRepository<MyHibernateModelClass, Long> {

@PreAuthorize("#entity == null || #entity.hasMetadadaWithId(principal.id)")
    @Override
    <S extends MyHibernateModelClass> S save(S entity);

    @PreFilter("filterObject == null || filterObject.hasMetadadaWithId(principal.id)")

    @Override
    <S extends MyHibernateModelClass> List<S> save(Iterable<S> entities);
    
    @PostAuthorize("returnObject.hasMetadadaWithId(principal.id)")
    @Override
    MyHibernateModelClassfindOne(Long integer);

    @PostFilter("filterObject.hasMetadadaWithId(principal.id)")

    @Override
    List<MyHibernateModelClass> findAll();
    
}

And that's all!

For any question, ask me!

Try it and have fun!

No hay comentarios:

Publicar un comentario