如果登录的用户无权查看特定字段,是否有任何方法可以动态排除 bean 属性被序列化?
例如,如果 bean 具有字段 A、B、C,那么在 REST 响应中,管理员可以看到字段 A、B、C,而简单用户只能看到字段 A、B。我如何注释字段 C 的吸气剂?我可以将此类注释与 Jersey 的 SecurityContext 集成吗?
我正在使用 Jersey 2.1 和 Jackson。
谢谢
一种可能的方法是使用@JsonView(另见JacksonJsonViews)。
意见:
// View definitions:
class Views {
static class User { }
static class Admin extends User { }
}
豆:
public class Bean {
@JsonView(Views.User.class)
private A a;
@JsonView(Views.User.class)
private B b;
@JsonView(Views.Admin.class)
private C c;
}
您需要按照用户指南中Jackson部分中的说明创建ContextResolver 。您可以向其中注入SecurityContext,从中可以找出用户所在的角色。您可能看起来像:ContextResolver
ContextResolver
@Provider
public class MyObjectMapperProvider implements ContextResolver<ObjectMapper> {
@Context
private SecurityContext securityContext;
@Override
public ObjectMapper getContext(Class<?> type) {
final ObjectMapper objectMapper = new ObjectMapper();
if (securityContext.isUserInRole("admin")) {
objectMapper.getSerializationConfig().setSerializationView(Views.Admin.class);
} else {
objectMapper.getSerializationConfig().setSerializationView(Views.User.class);
}
return objectMapper;
}
}
已经为类似的(更用户友好的)用例提交了 RFE(参见JERSEY-2013)。
如果您对具有不同用户角色的请求使用相同的 JAX-RS 资源,则应考虑以下解决方案:
@Provider
public class SecuritySerializerFilter extends JacksonJaxbJsonProvider {
@Context
SecurityContext securityContext;
@Override
public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
ObjectMapper current = locateMapper(type, mediaType);
setMapper(current.setSerializationConfig(
current.getSerializationConfig().withView(
securityContext.isUserInRole("admin") ? Views.Admin.class : Views.User.class
)
));
super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream);
}
}