JSON als Datenstruktur ist bei der Implementierung von Webservices kaum wegzudenken. Insbesondere Jackson als JSON Parser bietet eine ganze Reihe von Möglichkeiten, um auf die Generierung einzuwirken. Ein naheliegen Anwendungsfall hier z.B. das Ausblenden von bestimmten Attributen basierend auf Benutzer-Rollen oder Berechtigungen. Vorhang auf für: @JsonFilter
Ein Jackson Filter ist eine einfache Implementierung, die in aller Regel von SimpleBeanPropertyFilter ableitet und auf dessen Basis die Entscheidung getroffen wird, ob bestimmte Attribute im JSON vorhanden sind oder nicht
public class RolesFilter extends SimpleBeanPropertyFilter {
private final UserService userService;
private boolean valid(PropertyWriter writer) {
final RolesAllowed rolesAllowed = writer.getAnnotation(RolesAllowed.class);
return rolesAllowed == null || userService.hasRole(rolesAllowed.value())
&& super.include(writer);
}
}
In diesem Beispiel prüft der Filter auf das Vorhandensein einer zusätzlichen Annotation (RolesAllowed), die dazu verwendet wird, auf Ebene eines Attributes zu definieren, welche Benutzerrollen dieses Attribut sehen dürfen.
Ein solcher Filter muss nun im ObjectMapper aktiviert werden. Entweder lokal oder über eine entsprechende Initialisierungsmöglichkeit, hier z.B. über eine Spring Boot Configuration
@RequiredArgsConstructor
@Configuration
public class JacksonConfig {
private final UserService userService;
@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> {
var filterProvider = new SimpleFilterProvider();
filterProvider.addFilter("MyRoleFilter",new RolesFilter(userService)));
builder.filters(filterProvider);
};
}
}
Zusätzlich müssen alle DTO Klassen, die so gefiltert werden sollen, mit einer entsprechenden @JsonFilter – Deklaration versehen werden:
@JsonFilter("MyRoleFilter")
public class Material {
private UUID id;
private String name;
private Region region;
@RolesAllowed({"ROLE_ADMIN"})
private Supplier supplier;
}
Je nach Rolle des angemeldeten Users wird nun der Supplier Bestandteil der JSON Response oder nicht.