Chapter 2. REST API authorization rules

This section discusses authorization rules for restricting access to Neo4j through the REST API.

Administrators may require more fine-grained security policies in addition to the basic authorization and/or IP-level restrictions on the Web server. Neo4j supports administrators in allowing or disallowing access the specific aspects of the database based on credentials that users or applications provide.

To facilitate domain-specific authorization policies in Neo4j when using the REST API, security rules can be implemented and registered with the server. This makes scenarios such as user and role-based security and authentication against external lookup services possible. See org.neo4j.server.rest.security.SecurityRule in the javadocs downloadable from Maven Central (org.neo4j.app:neo4j-server).

The use of REST API Authorization Rules may interact unexpectedly with the built-in authentication and authorization (see the relevant sections in the Neo4j Operations Manual), if enabled.

2.1. Enforcing server authorization rules

In this example, a (dummy) failing security rule is registered to deny access to all URIs to the server by listing the rules class in neo4j.conf:

dbms.security.http_authorization_classes=my.rules.PermanentlyFailingSecurityRule

with the rule source code of:

public class PermanentlyFailingSecurityRule implements SecurityRule
{

    public static final String REALM = "WallyWorld"; // as per RFC2617 :-)

    @Override
    public boolean isAuthorized( HttpServletRequest request )
    {
        return false; // always fails - a production implementation performs
                      // deployment-specific authorization logic here
    }

    @Override
    public String forUriPath()
    {
        return "/*";
    }

    @Override
    public String wwwAuthenticateHeader()
    {
        return SecurityFilter.basicAuthenticationResponse(REALM);
    }
}

With this rule registered, any access to the server will be denied. In a production-quality implementation the rule will likely lookup credentials/claims in a 3rd-party directory service (e.g. LDAP) or in a local database of authorized users.

Example request

  • POST http://localhost:7474/db/data/node
  • Accept: application/json; charset=UTF-8

Example response

  • 401: Unauthorized
  • WWW-Authenticate: Basic realm="WallyWorld"

2.2. Using wildcards to target security rules

In this example, a security rule is registered to deny access to all URIs to the server by listing the rule(s) class(es) in neo4j.conf. In this case, the rule is registered using a wildcard URI path (where * characters can be used to signify any part of the path). For example /users* means the rule will be bound to any resources under the /users root path. Similarly /users*type* will bind the rule to resources matching URIs like /users/fred/type/premium.

dbms.security.http_authorization_classes=my.rules.PermanentlyFailingSecurityRuleWithWildcardPath

with the rule source code of:

public String forUriPath()
{
    return "/protected/*";
}

With this rule registered, any access to URIs under /protected/ will be denied by the server. Using wildcards allows flexible targeting of security rules to arbitrary parts of the server’s API, including any unmanaged extensions or managed plugins that have been registered.

Example request

  • GET http://localhost:7474/protected/tree/starts/here/dummy/more/stuff
  • Accept: application/json

Example response

  • 401: Unauthorized
  • WWW-Authenticate: Basic realm="WallyWorld"

2.3. Using complex wildcards to target security rules

In this example, a security rule is registered to deny access to all URIs matching a complex pattern. The config looks like this:

dbms.security.http_authorization_classes=my.rules.PermanentlyFailingSecurityRuleWithComplexWildcardPath

with the rule source code of:

public class PermanentlyFailingSecurityRuleWithComplexWildcardPath implements SecurityRule
{

    public static final String REALM = "WallyWorld"; // as per RFC2617 :-)

    @Override
    public boolean isAuthorized( HttpServletRequest request )
    {
        return false;
    }

    @Override
    public String forUriPath()
    {
        return "/protected/*/something/else/*/final/bit";
    }

    @Override
    public String wwwAuthenticateHeader()
    {
        return SecurityFilter.basicAuthenticationResponse(REALM);
    }
}

Example request

  • GET http://localhost:7474/protected/wildcard_replacement/x/y/z/something/else/more_wildcard_replacement/a/b/c/final/bit/more/stuff
  • Accept: application/json

Example response

  • 401: Unauthorized
  • WWW-Authenticate: Basic realm="WallyWorld"