小编典典

使用@RolesAllowed通过RESTEasy和Jackson过滤实体属性

java

使用RESTEasy和Jackson,是否可以@RolesAllowed在模型中使用注释,从而避免根据用户的角色在输出中序列化某些属性?

我已经找到了大量关于如何使用Jersey的文档,但是关于RESTEasy却没有。

我在此架构上受阻,因此切换库不是一个选择,并且也不像此处ObjectMapper说明的那样使用自定义,因为该模型足够大,以至于标记大型数据集的每个属性都太耗时用于正确的序列化。另外,这是指Jackson库的较旧版本,我不确定如何使其与新版本一起使用。

编辑

具体请参阅此博客文章,以了解我要完成的工作。请注意,这是特定于泽西岛的,到目前为止,我还没有找到有关RESTEasy的文档来完成此操作。


阅读 247

收藏
2020-11-30

共1个答案

小编典典

如果您不愿意使用@JsonView,可以考虑@JsonFilter。首先,您需要SimpleBeanPropertyFilter根据用户角色扩展和控制序列化:

public class RoleBasedPropertyFilter extends SimpleBeanPropertyFilter {

    private String allowedRole;

    public RoleBasedPropertyFilter(String allowedRole) {
        this.allowedRole = allowedRole;
    }

    @Override
    public void serializeAsField(Object pojo, JsonGenerator jgen,
                                 SerializerProvider provider, 
                                 PropertyWriter writer) throws Exception {

        PermitAll permitAll = writer.getAnnotation(PermitAll.class);
        if (permitAll != null) {
            serializeAsField(pojo, jgen, provider, writer);
            return;
        }

        DenyAll denyAll = writer.getAnnotation(DenyAll.class);
        if (denyAll != null) {
            writer.serializeAsOmittedField(pojo, jgen, provider);
            return;
        }

        RolesAllowed rolesAllowed = writer.getAnnotation(RolesAllowed.class);
        if (rolesAllowed != null) {
            if (!Arrays.asList(rolesAllowed.value()).contains(allowedRole)) {
                writer.serializeAsOmittedField(pojo, jgen, provider);
                return;
            }
        }

        // If no annotation is provided, the property will be serialized
        writer.serializeAsField(pojo, jgen, provider);
    }
}

要将过滤器应用于某个bean,请使用进行注释@JsonFilter("roleBasedPropertyFilter")

@JsonFilter("roleBasedPropertyFilter")
public class User {

    private String firstName;
    private String lastName;
    private String email;
    private String password;

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    @RolesAllowed({"ADMIN"})
    public String getEmail() {
        return email;
    }

    @DenyAll
    public String getPassword() {
        return password;
    }

    // Other getters and setters
}

然后,注册您的过滤器在你的ContextResolverObjectMapper

String currentUserRole = // Get role from the current user

FilterProvider filterProvider = new SimpleFilterProvider()
        .addFilter("roleBasedPropertyFilter", 
                new RoleBasedPropertyFilter(currentUserRole));

ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);

如果要将过滤器设置为“全局”,即要应用于所有bean,则可以创建一个混合类,并使用对其进行注释@JsonFilter("roleBasedPropertyFilter")

@JsonFilter("roleBasedPropertyFilter")
public class RoleBasedPropertyFilterMixIn {

}

然后将混合类绑定到Object

mapper.addMixIn(Object.class, RoleBasedPropertyFilterMixIn.class);
2020-11-30