Authentication in JanusGraph Server
Graham Wallis <grahamwallis.dev@...>
Hi,
I've been trying to use authentication over a websocket connection to a JanusGraph Server.
If I configure the server to use a SimpleAuthenticator and a TinkerGraph for the credentials, as described in the Tinkerpop documentation, it works.
In this mode, my gremlin-server.yaml is configured for authentication as follows:
where the tinkergraph-credentials.properties file is the same as the example from Tinkerpop:
My gremlin-server.yaml also has the following SSL configuration:
I've created a self-signed certificate for localhost, added it to the server.jks keystore (with the key password the same as the store password).
Because my client (console) is on the same machine as the server, I used the server.jks keystore as the truststore for the client, and created
a sasl-remote.yaml file for the client, with the following:
I can start a gremlin-console and connect to the server, using the credentials ("stephen", "password").
and subsequent remote operations against my (real) graph succeed.
The above all works nicely. I can step through the invocation of SimpleAuthenticator's authenticate() method in the server in the debugger and it does exactly what you'd expect.
If I try to do the same using a JanusGraph DB to store the credentials I can't get the client to authenticate.
I tried using the following janusgraph-credentials-server.properties file for my credentials store:
And changed my gremlin-server yaml as follows:
The ../cred/berkeley database is created during start of the gremlin-server. If I subsequeently stop the server and open the credentials database using a gremlin-console (locally) I can see that the default user has been added to it, the vertex is correctly labelled (as 'user') and the username and (hashed) password match. So the credentials store looks OK.
However, if I now create a connection to the server and try to perform an remote operation, it doesn't authenticate and always results in "Username and/or password are incorrect".
Stepping through the server code in the debugger, I noticed that the JanusGraphSimpleAuthenticator authenticate() method is never called, because the handler calls the SimpleAuthenticator's authenticate() method directly. This is probably fine as the former delegates to the latter anyway. But when the SimpleAuthenticator's authenticate() actually performs the credentials traversal, it does not find the user.
I wondered whether I shuold be using a JanusGraph specific authentication handler, but that doesn't look like it would help; for a websocket connection the SaslAndHMACAuthentiucationHandler will delegate to the channelRead method of its superclass, i.e. SaslAuthenticationHandler, which is the same as the above. The only difference I can see in the code is that the SimpleAuthenticator is using a Tinkerpop generic Graph to create its CredentialTraversalSource, whereas the JanusGraphSimpleAuthenticaor uses a JanusGraph.
Please can anyone can see what I'm doing wrong?
Best regards,
Graham
I've been trying to use authentication over a websocket connection to a JanusGraph Server.
If I configure the server to use a SimpleAuthenticator and a TinkerGraph for the credentials, as described in the Tinkerpop documentation, it works.
In this mode, my gremlin-server.yaml is configured for authentication as follows:
authentication: {
authenticator: org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator,
authenticationHandler: org.apache.tinkerpop.gremlin.server.handler.SaslAuthenticationHandler,
config: {
credentialsDb: conf/tinkergraph-credentials.properties
}
}
where the tinkergraph-credentials.properties file is the same as the example from Tinkerpop:
gremlin.graph=org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph
gremlin.tinkergraph.vertexIdManager=LONG
gremlin.tinkergraph.graphLocation=data/credentials.kryo
gremlin.tinkergraph.graphFormat=gryo
My gremlin-server.yaml also has the following SSL configuration:
ssl: {
enabled: true,
sslEnabledProtocols: [TLSv1.2],
keyStore: server.jks,
keyStorePassword: mykeystore
}
I've created a self-signed certificate for localhost, added it to the server.jks keystore (with the key password the same as the store password).
Because my client (console) is on the same machine as the server, I used the server.jks keystore as the truststore for the client, and created
a sasl-remote.yaml file for the client, with the following:
hosts: [localhost]}
port: 8182
serializer: { className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }}
username: stephen
password: password
connectionPool: {
enableSsl: true,
sslEnabledProtocols: [TLSv1.2],
trustStore: server.jks,
trustStorePassword: mykeystore
I can start a gremlin-console and connect to the server, using the credentials ("stephen", "password").
:remote connect tinkerpop.server conf/sasl-remote.yaml session
and subsequent remote operations against my (real) graph succeed.
The above all works nicely. I can step through the invocation of SimpleAuthenticator's authenticate() method in the server in the debugger and it does exactly what you'd expect.
If I try to do the same using a JanusGraph DB to store the credentials I can't get the client to authenticate.
I tried using the following janusgraph-credentials-server.properties file for my credentials store:
gremlin.graph=org.janusgraph.core.JanusGraphFactory
storage.backend=berkeleyje
storage.directory=../cred/berkeley
And changed my gremlin-server yaml as follows:
authentication: {
authenticator: org.janusgraph.graphdb.tinkerpop.gremlin.server.auth.JanusGraphSimpleAuthenticator,
authenticationHandler: org.apache.tinkerpop.gremlin.server.handler.SaslAuthenticationHandler,
config: {
defaultUsername: graham,
defaultPassword: sasl-password,
credentialsDb: conf/janusgraph-credentials-server.properties
}
}
The ../cred/berkeley database is created during start of the gremlin-server. If I subsequeently stop the server and open the credentials database using a gremlin-console (locally) I can see that the default user has been added to it, the vertex is correctly labelled (as 'user') and the username and (hashed) password match. So the credentials store looks OK.
However, if I now create a connection to the server and try to perform an remote operation, it doesn't authenticate and always results in "Username and/or password are incorrect".
Stepping through the server code in the debugger, I noticed that the JanusGraphSimpleAuthenticator authenticate() method is never called, because the handler calls the SimpleAuthenticator's authenticate() method directly. This is probably fine as the former delegates to the latter anyway. But when the SimpleAuthenticator's authenticate() actually performs the credentials traversal, it does not find the user.
I wondered whether I shuold be using a JanusGraph specific authentication handler, but that doesn't look like it would help; for a websocket connection the SaslAndHMACAuthentiucationHandler will delegate to the channelRead method of its superclass, i.e. SaslAuthenticationHandler, which is the same as the above. The only difference I can see in the code is that the SimpleAuthenticator is using a Tinkerpop generic Graph to create its CredentialTraversalSource, whereas the JanusGraphSimpleAuthenticaor uses a JanusGraph.
Please can anyone can see what I'm doing wrong?
Best regards,
Graham
Linux Foundation LFAIData
Project: Egeria