Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserialise JSON fields based on user role

Tags:

spring

jackson

I have some fields in a model that I only want to be returned when the logged in user has the role ROLE_ADMIN. I can use @JsonIgnore but that hides it for everyone. How can I make it hide dynamically?

like image 828
Tometoyou Avatar asked Nov 05 '25 21:11

Tometoyou


1 Answers

You should use Jackson Json Views technology to acheive it - it allows to choose a different set of fields to be serialized programatically. It is also supported by Spring

Consider you have a class Model with two properties: commonField which should be available for everyone and secretField which should be available only for certain users. You should create an hierarchy of views (any classes would work) and specify which field is available in which view using @JsonView annotation

package com.stackoverflow.jsonview;

import com.fasterxml.jackson.annotation.JsonView;

public class Model {

    public static class Public {}
    public static class Secret extends Public {}

    @JsonView(Public.class)
    private String commonField;

    @JsonView(Secret.class)
    private String secretField;

    public Model() {
    }

    public Model(String commonField, String secretField) {
        this.commonField = commonField;
        this.secretField = secretField;
    }

    public String getCommonField() {
        return commonField;
    }

    public void setCommonField(String commonField) {
        this.commonField = commonField;
    }

    public String getSecretField() {
        return secretField;
    }

    public void setSecretField(String secretField) {
        this.secretField = secretField;
    }

}

Now you can specify the view you want to use in concrete ObjectMapper

package com.stackoverflow.jsonview;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 */
public class ModelTest {

    @Test
    public void testSecretField() throws JsonProcessingException {
        Model model = new Model("commonField","secretField");
        assertEquals("{\"commonField\":\"commonField\",\"secretField\":\"secretField\"}", new ObjectMapper().writerWithView(Model.Secret.class).writeValueAsString(model));
        assertEquals("{\"commonField\":\"commonField\"}", new ObjectMapper().writerWithView(Model.Public.class).writeValueAsString(model));
    }

}

I am not sure if you can use declaratie approach to make spring choose the right view based on user role out of the box, so probably you will have to write some code like this:

@RequestMapping("/data")
public String getData(HttpServletRequest request) {
    Model model = service.getModel();
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper = request.isUserInRole("ROLE_ADMIN") ? objectMapper.writerWithView(Model.Secret.class) : objectMapper.writerWithView(Model.Public.class);
    return objectMapper.writeValueAsString(model);
}
like image 171
bedrin Avatar answered Nov 07 '25 14:11

bedrin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!