With RESTEasy and Jackson, is it possible to use the @RolesAllowed
annotation in my model, in order to avoid certain properties to be serialized in output, dependin
If you are not willing to use @JsonView, you could consider @JsonFilter. You first need to extend SimpleBeanPropertyFilter and control the serialization according to the user roles:
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);
}
}
To apply the filter to a certain bean, annotate it with @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
}
Then register your filter in your the ContextResolver for ObjectMapper:
String currentUserRole = // Get role from the current user
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("roleBasedPropertyFilter",
new RoleBasedPropertyFilter(currentUserRole));
ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);
If you want to make your filter "global", that is, to be applied to all beans, you can create a mix-in class and annotate it with @JsonFilter("roleBasedPropertyFilter")
:
@JsonFilter("roleBasedPropertyFilter")
public class RoleBasedPropertyFilterMixIn {
}
Then bind the mix-in class to Object
:
mapper.addMixIn(Object.class, RoleBasedPropertyFilterMixIn.class);