Spring Security and ABAC (Attribute Based Access Control)

salk31 picture salk31 · Aug 14, 2015 · Viewed 11.5k times · Source

We have a medium sized business app and we use Spring Security roles and permissions (RBAC) heavily with a big kludge to turn roles on and off for certain instances plus rules hidden in SpEL within @PreAuthorize tags.

I think what we have actually implemented (without knowing it is ABAC). XACML looks very complicated and bloated so I'm not keen on the answer here:

How to change Spring Security roles by context?

Has anybody done a light weight ABAC implementation without XACML? I have hopes that would give us separation of concerns as the domain objects just do @PreAuthorize(WRITE) etc and our authorisation policy would be decoupled from it.

From what I've read the basic principal of ABAC is very simple. You have an Action (very like a Permission) and a mechanism to resolve if the current Principal has that permission on a given Subject.

I'm aware of AccessDecisionVoter which is roughly the right sort of interface but I don't think it was intended for voting on permissions. However implementing our authorisation policy with instances of something like those seems very attractive.

Sorry for the rambling question! Basically I'm interesting in ABAC but would like to avoid home brew but worried what XACML is a jumbo jet when we need a Cessna.

Answer

Srijith Nair picture Srijith Nair · Aug 15, 2015

There seems to be two things you are aiming for:

  1. externalized authorization, where you want to move access control policies out of the code (or at least into a central place in the code and not scattered across the Spring code)
  2. attribute based authorization, where you want to use richer attributes than roles and permissions

I am not very sure of (2) since what you say you want to do, "action and a mechanism to resolve if the current Principal has that permission", is still, in my books, RBAC. Do you have other conditions on which access grant decisions will need to be based on? Location of the user, time of day, value of certain data in a database, properties of the resource being acted on etc.? If so, we stray into the ABAC world. Either way, I would say that RBAC is a subset of ABAC since a role is just one attribute.

Now, as for (1), the general pattern would be to first centralize the authorization engine and use the Spring annotations to call this authz. engine for access decisions. You have two choices here:

  • embedded authz. engine: where a library implements the engine and is called by the code just as a Java function. Could be a XACML engine or could be your own RBAC/ABAC implementation
  • as a network service: where a network based (micro) service answers access control decision questions. Could be a XACML engine or could be your own RBAC/ABAC implementation

In order to get the Spring based code to call this authz. engine, one approach would be to write your own Spring Security voter. Another way, which I found much easier, would be to write your own Spring Expression Language based expressions that you can then call with the existing @PreAuthorize, @PostAuthorize, @PreFilter and @PostFiler, sec:authorize tags and even from intercept-url conditions.

This is what I used when I worked on our Spring Security XACML PEP SDK. The approach should work equally well even if you decide not to use XACML for your access decision policies or the request/response communication.