Neo4j 2.2 Authentication and adding extra users

Token-based authentication is new in Neo4j 2.2, but how does it work?
The first thing to know is that it is enabled by default in conf/neo4j-server.properties by:

# Require (or disable the requirement of) auth to access Neo4j
dbms.security.auth_enabled=true

To understand the implementation, the main place to look is the org.neo4j.server.security.auth package which has some key interfaces, chiefly UserRepository, implemented by FileUserRepository (which stores salted, SHA-256 hashed credentials in data/dbms/auth) and an InMemoryUserRepository for testing. The FileUserRepository also includes a password change required field, a record that needs to change the password looks like:

foobar:SHA-256,253F558188A14B66FB2CCF8C1C75509CC9403E7276B3F1E275F6B13D0D45E730,35F68B1D6C8524CD32AFF1DF7C42F515:password_change_required

AuthManager is responsible for handling username/password authentication and will invoke the creation of the initial neo4j/neo4j user on startup if the UserRepository returns the numberOfUsers as 0.

In terms of setup, org.neo4j.server.modules.AuthorizationModule adds an
org.neo4j.server.rest.dbms.AuthorizationFilter to intercept all requests, it obtains credentials from the HTTP Authorization header by decoding the base64 encoded username:password.

The API includes rate limiting via RateLimitedAuthenticationStrategy to prevent brute-force repeated logon attempts from being processed.

How are users managed?

org.neo4j.server.rest.dbms.UserService provides a JAX-RS endpoint at /user to expose two AuthManager operations, a GET of an AuthorizationRepresentation of a user by passing the username on the path. The password of a user can be set by POSTing to /{username}/password – this can only be done when the requesting principal matches the username.

How do I add more users?

That is a very good question (avoiding the obviously dirty solution of directly modifying the data/dbms/auth file). As already mentioned the UserRepository has the ability to create a User, as used by the AuthManager newUser method, but where is this exposed?

Sadly the answer is that as far as I could tell it’s not at present, so is it a case of neo4j-shell & Groovy to the rescue?
Can we write a script that can obtain the protected AuthManager from the AbstractServer – nice idea in principle, but the shell uses RMI. It’s time for an unmanaged extension.

The code is available from GitHub here, in essence it adds a new REST endpoint to allow the neo4j user to creating other user accounts using a POST request to /useradd/{username} and including password=some_password within the payload.

You can build the extension using Maven’s package target, and copy the resultant jar file from target/neo4j-server-useradd-2.2.1.jar to the /plugins directory of the Neo4j server.

Additionally you’ll need to add the following line to conf/neo4j-server.properties:
org.neo4j.server.thirdparty_jaxrs_classes=org.neo4j.extension.server.unmanaged=/unmanaged

Then you can easily add users to the UserRepository (e.g.
curl --data "password=bar" --user neo4j:neo4j http://localhost:7474/unmanaged/useradd/foo), note that they’ll be made to change their passwords (as shown above in an earlier listing).

Summary

The 2.3 release will be enhancing this area with alternative authentication mechanisms (such as LDAP); if you need authorisation, then this can be handled at present using custom code implementing the org.neo4j.server.rest.security.SecurityRule interface (see the manual for more details).

Advertisements

9 responses to “Neo4j 2.2 Authentication and adding extra users

  1. Just a quick one, but when I try to build the extension with Maven I get the error:

    [INFO] BUILD FAILURE
    [INFO] ————————————————————————
    [INFO] Total time: 20.167 s
    [INFO] Finished at: 2015-06-25T18:28:53+01:00
    [INFO] Final Memory: 28M/180M
    [INFO] ————————————————————————
    [ERROR] Failed to execute goal org.neo4j.build.plugins:licensing-maven-plugin:1.
    7.5:check (list-all-licenses) on project neo4j-server-useradd: Generated file di
    ffers from the existing file.
    [ERROR] Generated: C:\Users\Sticky Kiwi\Desktop\neo4j-useradd-master\neo4j-usera
    dd-master\target\neo4j-server-useradd-2.2.1-NOTICE.txt
    [ERROR] Existing: C:\Users\Sticky Kiwi\Desktop\neo4j-useradd-master\neo4j-userad
    d-master\target\..\NOTICE.txt
    [ERROR] -> [Help 1]
    org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal o
    rg.neo4j.build.plugins:licensing-maven-plugin:1.7.5:check (list-all-licenses) on
    project neo4j-server-useradd: Generated file differs from the existing file.
    Generated: C:\Users\Sticky Kiwi\Desktop\neo4j-useradd-master\neo4j-useradd-maste
    r\target\neo4j-server-useradd-2.2.1-NOTICE.txt

  2. Yeah, I ran ‘mvn clean install -Dlicense.skip=true’ from the root folder of your project
    still the same error, but I think, and as information on doing *anything* auth-wise in Neo4j is scarce, it might be because I am using 2.2.2, 2.2.3 and 2.3.0-M02 on different Windows machines.
    You wouldn’t think it would be so hard to do this, all I want to do is create users so that they can authenticate to the Rest API with their own account.

    Thanks

  3. Just ran it again with -X and got this:
    org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.neo4j.build.plugins:licensing-maven-plugin:1.7.5:check (list-all-licenses) on project neo4j-server-useradd: Generated file differs from the existing file.
    Generated: C:\Users\Sticky Kiwi\Desktop\neo4j-useradd-master\neo4j-useradd-master\target\neo4j-server-useradd-2.2.1-NOTICE.txt
    Existing: C:\Users\Sticky Kiwi\Desktop\neo4j-useradd-master\neo4j-useradd-master\target\..\NOTICE.txt

  4. Sorted, ended up running
    mvn install “-Dlicensing.skip” (yes that is quoted) and it built first time, so yeah, thank you 🙂

  5. Erik Quaeghebeur

    I tried building this on linux, but get similar issues with the licensing:

    > mvn clean install -Dlicensing.skip=true

    [INFO] — license-maven-plugin:3:check (check-licenses) @ neo4j-server-useradd —
    [INFO] Checking licenses…
    [INFO] Missing header in: […]/neo4j-useradd/src/main/java/org/neo4j/extension/server/unmanaged/UserAddService.java
    [INFO] Missing header in: […]/neo4j-useradd/src/test/java/org/neo4j/extension/server/unmanaged/UserDeleteServiceTest.java
    [INFO] Missing header in: […]/neo4j-useradd/src/test/java/org/neo4j/extension/server/unmanaged/UserAddServiceTest.java
    [INFO] Missing header in: […]/temp/neo4j-useradd/src/main/java/org/neo4j/extension/server/unmanaged/UserDeleteService.java
    [INFO] ————————————————————————
    [INFO] BUILD FAILURE
    [INFO] ————————————————————————
    [INFO] Total time: 1.711 s
    [INFO] Finished at: 2016-02-04T13:56:00+01:00
    [INFO] Final Memory: 13M/219M
    [INFO] ————————————————————————
    [ERROR] Failed to execute goal org.neo4j.build.plugins:license-maven-plugin:3:check (check-licenses) on project neo4j-server-useradd: Some files do not have the expected license header

    Shaine’s suggestion did not work for me.

    Also: building for neo4j 2.3.2 can be done just by changing the version numbers, or did the API change?

    • Hi Erik,

      It’s working for me on OSX:


      neo4j-useradd$ mvn license:check
      [INFO] Scanning for projects...
      [INFO]
      [INFO] ------------------------------------------------------------------------
      [INFO] Building Neo4j - Useradd extension 2.2.1
      [INFO] ------------------------------------------------------------------------
      [INFO]
      [INFO] --- license-maven-plugin:3:check (default-cli) @ neo4j-server-useradd ---
      [INFO] Checking licenses...
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time: 2.778 s
      [INFO] Finished at: 2016-02-04T13:58:35+00:00
      [INFO] Final Memory: 8M/81M
      [INFO] ------------------------------------------------------------------------
      neo4j-useradd$

      One thing might be to try mvn license:format to see if there any formatting oddities?

      I haven’t yet tried it for 2.3.2, but that could be done by changing the version number – I’m not aware of any API changes.

  6. Erik Quaeghebeur

    Ok, I used `mvn license:format` and that seems to have done ‘something’, although perhaps not something relevant for what I did to ‘fix’ things. (I got it to build.)

    Namely, I copied the generated `LICENSES.txt` and `NOTICE.txt` over the supplied ones. The difference (what was added) was the following:

    Apache Software License, Version 2.0
    Apache Commons Lang

    BSD License
    ASM Core
    scala-parser-combinators

    I haven’t had the opportunity to test the jar file yet. (I’m using neo4j 2.3.2 and modified the version strings for that.)

  7. Pingback: Open Gov Data talk at Neo4j London User Group | Lean Java Engineering

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s