0

I have a class named Order shown below.

    class Order{
    private int id;
    private String name;
    private String amount;
    //getters and setters
    }

Using Spring security, I need to be able to control the data that is being returned as a response from Spring Controller. For say, Admin can view all the data of Order, but customer can see only name and amount. How can I filter the JSON data with Spring Security.So, final output for admin should be

     [{id:1,name:order1,amount:100}, {id:2,name:order2,amount:200}] 

and output for customer should be

    [{name:order1,amount:100}, {name:order2,amount:200}].

Is there any way to do this

Raghavendra
  • 3,876
  • 4
  • 22
  • 41

1 Answers1

0

you could hack it a bit with Spring Data and Spring Security:

public interface FooRepository extends CrudRepository<Foo, Long> {

    @Query(
            value = "select id, amount, case when ?#{hasRole('admin')} then name else null end as name from foo where id=?1",
            nativeQuery = true
    )
    Foo findOne(Long id);
}

You'd need to add an EvaluationContextExtensionSupport bean. This lets you use Spring Security expressions in Spring Data queries:

@Component
public class MyEvaluationContextExtensionSupport extends EvaluationContextExtensionSupport{

    @Override
    public String getExtensionId() {
        return "security";
    }

    @Override
    public SecurityExpressionRoot getRootObject() {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return new SecurityExpressionRoot(authentication) {};

    }
}

Or you could try Projections with Spring Data REST

//untested:
@Projection(name = "detailed", types = Foo.class)
public interface FooDetailProjection {

    @Value("?#{ hasRole('admin')? target.name: null}")
    public String getName();
}

Or consider using Column Security directly in your database.

Neil McGuigan
  • 46,580
  • 12
  • 123
  • 152