Authorization
Introduction
See Understanding RESTHeart Security for an high level view of the RESTHeart security model.
restheart-security is built around a pluggable architecture. It comes with a strong security implementation but you can easily extend it by implementing plugins. This section documents the authorizers available out-of-the-box.
RESTHeart by default offers two types of authorizers:
- RESTHeart Authorizer.
- Request Predicates Authorizer.
However, it’s even possible to develop custom authorizers. Please refer to Develop Security Plugins for more information.
RESTHeart Authorizer
Available since RESTHeart Platform v4.1
RESTHeart Authorizer authorizes requests according to the Access Control List defined in a MongoDB collection, seamlessly connecting restheart-platform-security
with restheart-platform-core
.
RESTHeart Authorizer is robust, battle-tested and suggested for production use.
The configuration allows:
- defining the collection to use to store ACL documents (
acl-uri
). - enabling the root role (
root-role
): users with root role, can execute any requests, regardless of the permissions set in the ACL. - controlling the ACL caching.
authorizers:
- name: rhAuthorizer
class: com.restheart.security.plugins.authorizers.RHAuthorizer
args:
acl-uri: /acl
root-role: admin
cache-enabled: true
cache-size: 1000
cache-ttl: 5000
cache-expire-policy: AFTER_WRITE
Format of an ACL document
An example ACL document follows:
{
"_id": { "$oid": "5d9485639eab3a852d48a1de" },
"predicate": "path-prefix[/blog] and (method[GET] or method[POST])",
"roles": ["editor"],
"priority": 1,
"readFilter": {
"_$or": [
{ "author": { "_$eq": "%USER" } },
{ "status": { "_$eq": "PUBLISHED" } }
]
},
"writeFilter": { "author": { "_$eq": "%USER" } }
}
The properties of the ACL document are:
property | type | description |
---|---|---|
predicate | string | If the undertow predicate resolves the request then the request is authorized. |
roles | JSON array of strings | The roles that are applied the ACL document. The special role $unauthenticated applies to requests that are not authenticated. |
priority | number | A request might fulfill several predicates; an ACL document with higher priority has higher evaluation precedence. |
readFilter | null or JSON object |
An optional filter that is added to GET requests when authorized by this ACL document. |
writeFilter | null or JSON object |
An optional filter that is added to write requests when authorized by this ACL document. |
Using readFilter and writeFilter
readFilter
and writeFilter
allows to partition data by roles.
The example ACL document applies to users with editor
role. A user with this role can execute the requests GET /blog
and POST /blog
.
The readFilter
applies to GET requests. The example ACL document limits the returned /blog
documents to the ones that were published or that were created by the authenticated user.
The writeFilter
applies to write request. The example ACL document allows the requests to only modify the documents that were created by the authenticated user.
writeFilter
only limits updates and cannot avoid creating documents that don’t match the filter. The properties used in the filter should be set using Interceptors or Request Transformers.
readFilter
and writeFilter
can use the following variables:
variable | resolved to | example |
---|---|---|
%USER | the string id of the authenticated user | match documents with author property equal to the id of the authenticated user {"author":"%USER"} |
%ROLES | the roles array of the authenticated user | match documents with roles array property containing any role of the authenticated user {"roles": {"_$in": %ROLES } |
%NOW | the current date as {"$date": 1570027863000 } |
match documents with timestamp date property less than (before) the current date {"timestamp":{"_$lt": "%NOW"}} |
Request Predicates Authorizer
RequestPredicatesAuthorizer allows defining roles permissions in a YAML configuration file using the Undertow predicate language.
authorizers:
name: requestPredicatesAuthorizer
class: org.restheart.security.plugins.authorizers.RequestPredicatesAuthorizer
args:
conf-file: ./etc/acl.yml
The file acl.yml
defines the role based permissions. An example follows:
## configuration file for requestPredicatesAuthorizer
permissions:
# OPTIONS is always allowed
- role: $unauthenticated
predicate: path-prefix[path="/"] and method[value="OPTIONS"]
- role: $unauthenticated
predicate: path-prefix[path="/echo"] and method[value="GET"]
- role: admin
predicate: path-prefix[path="/"] and method[value="OPTIONS"]
- role: admin
predicate: path-prefix[path="/"]
- role: user
predicate: path-prefix[path="/"] and method[value="OPTIONS"]
- role: user
predicate: path-prefix[path="/secho"] and method[value="GET"]
- role: user
predicate: path[path="/secho/foo"] and method[value="GET"]
- role: user
predicate: (path[path="/echo"] or path[path="/secho"]) and method[value="PUT"]
# This to check the path-template predicate
- role: user
predicate: path-template[value="/secho/{username}"] and equals[%u, "${username}"]
# This to check the regex predicate
- role: user
predicate: regex[pattern="/secho/(.*?)", value="%R", full-match=true] and equals[%u, "${1}"]