Jackson Json serialization: exclude property respect to the role of the logged user

前端 未结 2 460
清歌不尽
清歌不尽 2021-01-28 01:41

Is there any way to dynamically exclude a bean property from being serialized if the logged user has not the permissions to see a specific field?

For example, if a bean

相关标签:
2条回答
  • 2021-01-28 02:27

    If you use the same JAX-RS resources for requests with different user roles, you should consider the following solution:

    @Provider
    public class SecuritySerializerFilter extends JacksonJaxbJsonProvider {
        @Context
        SecurityContext securityContext;
    
        @Override
        public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
    
            ObjectMapper current = locateMapper(type, mediaType);
            setMapper(current.setSerializationConfig(
                current.getSerializationConfig().withView(
                    securityContext.isUserInRole("admin") ? Views.Admin.class : Views.User.class
                )
            ));
    
            super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream);
        }
    }
    
    0 讨论(0)
  • 2021-01-28 02:30

    One possible approach would be to use @JsonView (see also JacksonJsonViews).

    Views:

    // View definitions:
    class Views {
        static class User { }
        static class Admin extends User { }
    }
    

    Bean:

    public class Bean {
    
        @JsonView(Views.User.class)
        private A a;
        @JsonView(Views.User.class)
        private B b;
    
        @JsonView(Views.Admin.class)
        private C c;
    }
    

    You would need to create a ContextResolver as described in Jackson section in the user guide. You can inject SecurityContext to this ContextResolver from which you can find out what role is a user in. Your ContextResolver may look like:

    @Provider
    public class MyObjectMapperProvider implements ContextResolver<ObjectMapper> {
    
        @Context
        private SecurityContext securityContext;
    
        @Override
        public ObjectMapper getContext(Class<?> type) {
            final ObjectMapper objectMapper = new ObjectMapper();            
    
            if (securityContext.isUserInRole("admin")) {
                objectMapper.getSerializationConfig().setSerializationView(Views.Admin.class);
            } else {
                objectMapper.getSerializationConfig().setSerializationView(Views.User.class);
            }
    
            return objectMapper;
        }
    }
    

    EDIT 1:

    There is a RFE filed for a similar (more user friendly) use case already (see JERSEY-2013).

    0 讨论(0)
提交回复
热议问题