spring security - example - Spring Data Rest: Proyección basada en seguridad
spring security login with rest service (3)
No, las proyecciones REST de Spring Data no son compatibles con esto.
Estoy usando la versión actual de Spring Data Rest y Spring Data JPA y tengo la siguiente entidad:
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private String password;
private String email;
...getter/setter methods...
}
También estoy usando Spring Security
.
Mi repositorio de usuarios:
@RepositoryRestResource(
collectionResourceRel = "user",
path = "user",
excerptProjection = UserSimpleProjection.class)
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
}
Por ejemplo:
- El usuario 1 está conectado
- El usuario 1 solicita
http://localhost:8080/user/1
: todos los campos están visibles - El usuario 1 solicita
http://localhost:8080/user/2
- soloname
muestran laid
y elname
.
Probé diferentes soluciones con Jackson, ninguna de ellas resolvió mi problema:
- Uso de JsonView : no encontré ninguna manera de cambiar la vista del
ObjectMapper
función del usuario que haya iniciado sesión. - Implementé diferentes filtros Jackson como se describe here con el mismo problema que no encontré manera de cambiar la configuración de
ObjectMapper
para las diferentes solicitudes.
Luego encontré Projections .
Creé una proyección:
@Projection(name = "simple", types = User.class)
public interface UserSimpleProjection {
public Long getId();
public String getName();
}
y otro detallado:
@Projection(name = "detailed", types = User.class)
public interface UserDetailProjection extends UserSimpleProjection{
public String getEmail();
}
Hasta ahora todo bien, obtengo resultados diferentes dependiendo de mi solicitud.
¿Hay alguna forma de cambiar automáticamente la proyección según Spring Security y / o limitar diferentes Proyecciones para diferentes roles?
Puede agregar una propiedad de valor "virtual" a la proyección que invoque un método de servicio con verificaciones de seguridad:
@Projection(name = "detailed", types = User.class)
public interface UserDetailProjection extends UserSimpleProjection{
@Value("#{@userService.checkAccess(target)? target.email : null}")
public String getEmail();
}
Donde su componente UserService
personalizado se volvería true
si el correo electrónico estuviera expuesto o simplemente tuviera @PreAuthorize
en @PreAuthorize
checkAccess(..)
para lanzar una AccessDeniedException
lo que sea mejor para usted.
Tenga en cuenta que la propiedad de target
en el SpEL contiene el objeto original, proporcionado por Spring-DATA.
También puede hacerlo usando un RegexRequestMatcher en su configuración de Spring Security de la siguiente manera:
.regexMatchers(HttpMethod.GET,"/user/.*projection=simple.*").hasRole("ROLE_ADMIN")