1

I want to filter object properties based on authentication or even roles. So, for example full user profile will be returned for authenticated user and filterd for non authenticated.

How can I achieve it with MappingJacksonHttpMessageConverter? I have already declared custom beans for Jaskon:

 <bean id="objectMapper" class="com.example.CustomObjectMapper"/>

    <bean id="MappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="objectMapper" ref="objectMapper"/>
    </bean>

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="order" value="1" />
        <!-- <property name="customArgumentResolver" ref="sessionParamResolver"/> -->
        <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <!-- <property name="conversionService" ref="conversionService" />  -->
            <!-- <property name="validator" ref="validator" /> -->
        </bean>
        </property>
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
                <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
                <bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
                <bean class="org.springframework.http.converter.FormHttpMessageConverter" />
                <ref bean="MappingJacksonHttpMessageConverter"/>
            </list>
        </property>
    </bean>

Note: In controllers I am writing results as:

public void writeJson (Object jsonBean, HttpServletResponse response) {
        MediaType jsonMimeType = MediaType.APPLICATION_JSON;
        if (jsonConverter.canWrite(jsonBean.getClass(), jsonMimeType)) {
            try {
                jsonConverter.write(jsonBean, jsonMimeType, new ServletServerHttpResponse(response));
            } catch (IOException m_Ioe) {
            } catch (HttpMessageNotWritableException p_Nwe) {
            }   catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            log.info("json Converter cant write class " +jsonBean.getClass() );
        }
    }
vacuum
  • 2,273
  • 3
  • 20
  • 32

2 Answers2

0

If you're wanting to return two separate types of JSON objects (e.g. fullProfile and partialProfile), then you would be best-off making two different services with two different urls. Then you could control access to those urls in the normal manner with Spring Security's intercept-url tags.

Tim Pote
  • 27,191
  • 6
  • 63
  • 65
0

I did most of that here https://stackoverflow.com/a/39168090/6761668

All you need to do is pencil in your own security rules, perhaps injecting the current user and deciding what to include or not based on their role. I used an annotation on the entity column:

  import java.lang.annotation.Retention;
  import java.lang.annotation.RetentionPolicy;
  import java.util.Set;
  @Retention(RetentionPolicy.RUNTIME)
  public @interface MyRestricted {
    String[] permittedRoles() default {};
  }

The column looked like this:

    @Column(name = "DISCOUNT_RATE", columnDefinition = "decimal", precision = 7, scale = 2)
    @MyRestricted(permittedRoles = { "accountsAdmin", "accountsSuperUser" })
    private BigDecimal discountRate; 

The rules looked like this:

    final MyRestricted roleRestrictedProperty = pWriter.findAnnotation(MyRestricted.class);
    if (roleRestrictedProperty == null) {
        // public item
        super.serializeAsField(pPojo, pJgen, pProvider, pWriter);
        return;
    } 

    // restricted - are we in role?
    if (permittedRoles.contains(myRole)) {
        super.serializeAsField(pPojo, pJgen, pProvider, pWriter);
        return;
    }
    // Its a restricted item for ME
    pWriter.serializeAsOmittedField(pPojo, pJgen, pProvider);
Community
  • 1
  • 1
bigbadmouse
  • 216
  • 1
  • 11