1

如果登录的用户无权查看特定字段,是否有任何方法可以动态排除 bean 属性被序列化?

例如,如果 bean 具有字段 A、B、C,那么在 REST 响应中,管理员可以看到字段 A、B、C,而简单用户只能看到字段 A、B。我如何注释字段 C 的吸气剂?我可以将此类注释与 Jersey 的 SecurityContext 集成吗?

我正在使用 Jersey 2.1 和 Jackson。

谢谢

4

2 回答 2

4

一种可能的方法是使用@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,从中可以找出用户所在的角色。您可能看起来像:ContextResolverContextResolver

@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;
    }
}

编辑1:

已经为类似的(更用户友好的)用例提交了 RFE(参见JERSEY-2013)。

于 2013-08-09T11:14:46.377 回答
0

如果您对具有不同用户角色的请求使用相同的 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);
    }
}
于 2014-11-27T14:54:56.703 回答