Spring Data Rest:基于安全的投影 [英] Spring Data Rest: Security based projection
问题描述
我使用的是当前版本的 Spring Data Rest 和 Spring Data JPA 并具有以下实体:
I am using the current version of Spring Data Rest and Spring Data JPA and have following entity:
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private String password;
private String email;
...getter/setter methods...
}
我也在使用 Spring Security
.
我的用户存储库:
@RepositoryRestResource(
collectionResourceRel = "user",
path = "user",
excerptProjection = UserSimpleProjection.class)
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
}
例如:
- 用户 1 已登录
- 用户 1 请求
http://localhost:8080/user/1
- 所有字段都可见 - 用户 1 请求
http://localhost:8080/user/2
- 只有id
和name
可见.
- User 1 is logged in
- User 1 requests
http://localhost:8080/user/1
- all fields are visible - User 1 requests
http://localhost:8080/user/2
- justid
andname
are visible.
我与 Jackson 尝试了不同的解决方案,但没有一个解决了我的问题:
I tried different solutions with Jackson, none of them solved my problem:
- 使用 JsonView:我发现没有办法改变
ObjectMapper<的视图/code> 取决于登录的用户
- 按照此处的描述实施了不同的 Jackson 过滤器,但遇到了同样的问题,我发现无法更改 code>ObjectMapper 针对不同请求的配置.
- Use of JsonView: I found no way, to change the view for the
ObjectMapper
depending on the logged in User - Implemented different Jackson Filters as described here with the same issue that I found no way to change the
ObjectMapper
config for the different requests.
然后我发现预测.
我创建了一个投影:
@Projection(name = "simple", types = User.class)
public interface UserSimpleProjection {
public Long getId();
public String getName();
}
还有一个详细的:
@Projection(name = "detailed", types = User.class)
public interface UserDetailProjection extends UserSimpleProjection{
public String getEmail();
}
到目前为止一切顺利,根据我的要求,我得到了不同的结果.
So far so good, I get different results depending on my request.
有没有办法根据 Spring Security 自动切换投影和/或限制不同角色的不同投影?
Is there a way to automatically switch the projection depending on Spring Security and/or limit different Projections for different roles?
推荐答案
您可以将虚拟"值属性添加到调用具有安全检查的服务方法的投影中:
You can add a "virtual" value property into the projection that invoke a service method with security checks:
@Projection(name = "detailed", types = User.class)
public interface UserDetailProjection extends UserSimpleProjection{
@Value("#{@userService.checkAccess(target)? target.email : null}")
public String getEmail();
}
如果电子邮件应该公开或在 checkAccess(..)
抛出 AccessDeniedException
任何对你更好的东西.
Where your custom UserService
component would return true
if email should be exposed or simply has @PreAuthorize
on checkAccess(..)
to throw an AccessDeniedException
whatever is better for you.
注意,SpEL 中的 target
属性保存了原始对象 - 由 Spring-DATA 提供.
Note, the target
property in the SpEL holds the original object - provided by Spring-DATA.
这篇关于Spring Data Rest:基于安全的投影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!