Neo4j Single Sign-On (SSO) Configuration
This tutorial provides detailed examples of how to configure Single Sign-On (SSO) for several identity providers. It also presents frequently asked questions and solutions to common problems encountered when configuring SSO.
Neo4j supports SSO authentication and authorization through identity providers that implement the OpenID Connect standard.
Note that the following configurations are crafted for a Neo4j Browser served on http://localhost:7474/browser/
(the default URL when starting the database on localhost
).
The redirect URI http://localhost:7474/browser/?idp_id={{provider}}&auth_flow_step=redirect_uri
should be modified when reproducing these examples in the identity
providers substituting for the one serving the browser application.
SSO works in the following way:
-
The server (Neo4j database) contacts the identity provider (Okta, Azure, Google, etc) and fetches the JSON Web Keys (JWKs) from the provider.
-
The client (e.g. Bloom, Neo4j Browser etc.) asks the user for credentials and contacts the identity provider.
-
The identity provider responds with a JSON Web Token (JWT), a JSON containing fields (claims), relative to the user (email, audience, groups, etc).
-
The client provides the server the JWT and the server verifies its signature with the JWKs.
1. Okta
This example shows how to configure Okta for authentication and authorization using access tokens.
First, configure the client with the appropriate redirect URI. Group assignments can be skipped in this step:


Note the client id and the domain (for the well known OpenIDC connect endpoint) will be used later in our Neo4j config:

We will create groups in Okta, assign users to them (the user can be added to a group either on user creation or editing the group) and map them in the neo4j.conf
to native groups:

Configure the default authorization server (the one that shows api://default
as audience) to return the groups
claim in access tokens:


The neo4j.conf
configuration used is:
dbms.security.authentication_providers=oidc-okta
dbms.security.authorization_providers=oidc-okta
dbms.security.oidc.okta.display_name=Okta
dbms.security.oidc.okta.auth_flow=pkce
dbms.security.oidc.okta.well_known_discovery_uri=https://dev-21056049.okta.com/oauth2/default/.well-known/openid-configuration
dbms.security.oidc.okta.audience=api://default
dbms.security.oidc.okta.claims.username=sub
dbms.security.oidc.okta.claims.groups=groups
dbms.security.oidc.okta.params=client_id=0oa3oq6uw3uSOBf8y5d7;response_type=code;scope=openid profile email
dbms.security.oidc.okta.authorization.group_to_role_mapping= "engineers" = admin; \
"collaborators" = reader
Note that the token_type_principal
and the token_type_authentication
were omitted, which means that access tokens are used instead.
You can now log in with Okta using the email of an engineer
role user that results in an admin
role in the database:

2. Azure Active Directory (AAD)
This example shows how to configure AAD for authentication and authorization using id tokens.
First, configure the client with the appropriate redirect URI:

Take note of the client id and the domain (for the well-known OpenIDC connect endpoint) as they are used later in your Neo4j config:

Create groups in the Azure AD console, assign users to them and map them in the neo4j.conf
to native groups.
In this case the groups claim in the JWT will contain the id of the group, so we will need to map that id to the desired native role later on:

Configure the server to return the groups claim in identity tokens, modifying the Manifest of the registered application:

The neo4j.conf
configuration used is:
dbms.security.authentication_providers=oidc-azure
dbms.security.authorization_providers=oidc-azure
dbms.security.oidc.azure.display_name=Azure
dbms.security.oidc.azure.auth_flow=pkce
dbms.security.oidc.azure.well_known_discovery_uri=https://login.microsoftonline.com/ce976899-299d-4a01-91e5-a5fee8f98626/v2.0/.well-known/openid-configuration
dbms.security.oidc.azure.audience=c2830ff5-86d9-4e38-8a2b-9efad6f3d06d
dbms.security.oidc.azure.claims.username=email
dbms.security.oidc.azure.claims.groups=groups
dbms.security.oidc.azure.params=client_id=c2830ff5-86d9-4e38-8a2b-9efad6f3d06d;response_type=code;scope=openid profile email
dbms.security.oidc.azure.config=token_type_principal=id_token;token_type_authentication=id_token
dbms.security.oidc.azure.authorization.group_to_role_mapping= "e8b6ddfa-688d-4ace-987d-6cc5516af188" = admin; \
"9e2a31e1-bdd1-47fe-844d-767502bd138d" = reader
You can now log in with Azure using the email of an engineer
role user that results in an admin
role in the database:

3. Google
This example shows how to use Google OpenIDC for authentication using id tokens in conjunction with native authorization.
Configuring the client and the redirect URI:


SSO authorization does not work with Google, since the JWT returned by Google does not contain information about the groups a user belongs to and cannot be configured to. It is recommended to use native (or another flavor) authorization by creating a native version of the user in Neo4j. |
The role assigned to the email used to log in with SSO, in this case alice@neo4j-test.com
, should have GRANT ROLE
permissions in the database (native
authentication temporarily enabled):
CREATE USER `alice@neo4j-test.com` SET PASSWORD 'pass';
GRANT ROLE admin to `alice@neo4j-test.com`;
The neo4j.conf
configuration used is:
dbms.security.authentication_providers=oidc-google
dbms.security.authorization_providers=native
dbms.security.oidc.google.display_name=Google
dbms.security.oidc.google.auth_flow=pkce
dbms.security.oidc.google.well_known_discovery_uri=https://accounts.google.com/.well-known/openid-configuration
dbms.security.oidc.google.audience=345461137297-v9brpjmgbvbm3d5s9fq65tktevosd3rn.apps.googleusercontent.com
dbms.security.oidc.google.claims.username=email
dbms.security.oidc.google.params=client_id=345461137297-v9brpjmgbvbm3d5s9fq65tktevosd3rn.apps.googleusercontent.com;response_type=code;scope=openid profile email
dbms.security.oidc.google.token_params=client_secret=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
dbms.security.oidc.google.config=token_type_principal=id_token;token_type_authentication=id_token
You can now log in with Google using the email address and get the admin
role when doing so:

Note that the native authentication is disabled, otherwise someone could log in to alice@neo4j-test.com natively with the set password. |
4. FAQ
4.1. When should pkce be used as auth flow?
Assuming the client (in this case Neo4j Browser or Bloom) can be accessed through the public internet, always use pkce
auth-flow rather than implicit
.
This is because the later one requires a client secret to be available to the public client.
In general, if both flows are available, it is recommended to opt for pkce
given increased security with respect to implicit
.
4.2. Is Google authentication secure if it has a client secret in the config listed above?
Yes.
Google uses the pkce flow, but sometimes identity providers also use a client secret to ensure the client asking for a token is the one using it
(pkce does not ensure that). The client secret does not add any additional security as it is public , but the pkce
flow provides sufficient security.
4.3. Could not parse JWT of type "access_token"
When getting the message Failed to get credentials: Could not parse JWT of type "access_token"
on Browser it probably means the provider only
accepts id tokens.

Change to id tokens in your neo4j.conf
:
dbms.security.oidc.{{provider}}.config=token_type_principal=id_token;token_type_authentication=id_token
4.4. When should identity tokens vs access tokens be used?
In general, it is safer to use access tokens when possible due to them being shorter-lived. That means if authorization permissions change on the identity provider, Neo4j would fail authorization and Browser would try to reconnect and reflect the changed permissions faster than if id tokens were used.
4.5. How to debug further problems with the configuration
Apart from the logs available at logs/debug.log
and logs/security.log
in the Neo4j path, the best way to debug this feature is to use a web-development
console in your web browser when doing the SSO authentication flow with Bloom or Browser.
This could reveal potential problems as the one presented below with an example identity provider and the Cross-Origin Request policy:

The solution involves adding the redirect domain to the list of allowed domains in the provider (in this case localhost:8080
):

Was this page helpful?