使用@RolesAllowed使用RESTEasy和Jackson

时间:2017-06-13 12:45:27

标签: java jackson resteasy

使用RESTEasy和Jackson,是否可以在我的模型中使用@RolesAllowed注释,以避免某些属性在输出中被序列化,具体取决于用户的角色?

我已经找到了大量关于如何使用Jersey进行此操作的文档,但没有任何关于RESTEasy的文档。

我在此体系结构上被阻止,因此切换库不是一个选项,并且使用自定义ObjectMapper,因为解释here也不是一个选项,因为模型足够大,也可以标记大型数据集的每个属性以进行正确的序列化非常耗时。另外,这是指Jackson库的旧版本,我不确定如何使用新版本。

修改

具体请参阅this blog post以了解我要完成的工作。请注意,这是特定于Jersey的,到目前为止,我没有找到有关RESTEasy的文档来完成此任务。

1 个答案:

答案 0 :(得分:2)

如果您不愿意使用@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
        serializeAsField(pojo, jgen, provider, writer);
    }
}

要将过滤器应用于某个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);

如果你想使你的过滤器" global",即要应用于所有bean,你可以创建一个混合类并用@JsonFilter("roleBasedPropertyFilter")注释它:

@JsonFilter("roleBasedPropertyFilter")
public class RoleBasedPropertyFilterMixIn {

}

然后将混合类绑定到Object

mapper.addMixIn(Object.class, RoleBasedPropertyFilterMixIn.class);