User authentication
LdapLoginModule
Configure Kpow to read authentication and role information from LDAP.
For specifics on JAAS / LDAP configuration see the Jetty LdapLoginModule docs.
Steps to enable LDAP
To enable LdapLoginModule authentication you must:
- Set the
AUTH_PROVIDER_TYPE=jetty
environment variable. - Create a JAAS configuration file
- Start the JAR or Docker container with the
java.security.auth.login.config
Java parameter set to the location of your JAAS configuration file.
Configuration
Environment variable configuration
To activate Jetty JAAS authentication set the environment variable AUTH_PROVIDER_TYPE=jetty
JAAS configuration file
Create a JAAS LDAP configuration file (the kpow realm is very important).
Your JAAS LDAP configuration will vary depending on your LDAP server structure:
kpow {
io.kpow.jaas.spi.LdapLoginModule required
contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
hostname="localhost"
port="10389"
bindDn="uid=admin,ou=system"
bindPassword="AES:ARAOyh4tygxSknnTNknnuFXG+PYr0oLlN9UO/0XSq4RSOw=="
authenticationMethod="simple"
useLdaps="false"
userBaseDn="OU=Users,DC=example,DC=com"
userRdnAttribute="uid"
userIdAttribute="cn"
userPasswordAttribute="userPassword"
userObjectClass="inetOrgPerson"
roleBaseDn="OU=Groups,DC=example,DC=com"
roleNameAttribute="roleName"
roleMemberAttribute="uniqueMember"
roleObjectClass="groupOfUniqueNames";
forceBindingLogin="true"
debug="true"
};
Encrypt the LDAP bindPassword
Optionally encrypt the bindPassword parameter of your JAAS configuration, see the Kpow Secure Configuration Guide for details.
Kpow startup
Start the JAR or Docker container with the java.security.auth.login.config
Java parameter set to the location of your JAAS configuration file.
The method for setting this Java parameter differs slightly depending on if you are using the Kpow JAR or Docker container.
JAR startup
Start the JAR with the java.security.auth.login.config
Java parameter set to the location of your JAAS configuration file.
ENVIRONMENT_NAME="Trade Book (Staging)" \
BOOTSTRAP="127.0.0.1:9092,127.0.0.1:9093,127.0.0.1:9094" \
# more env vars ..
AUTH_PROVIDER_TYPE="jetty" \
java -Djava.security.auth.login.config=/opt/kpow/jaas/ldap-jaas.conf -jar -Xmx4G /opt/kpow/kpow-java11-latest.jar
Docker container startup
Start Docker container with the java.security.auth.login.config
Java parameter set to the location of your JAAS configuration file.
Note: The JAAS configuration file must be made available to Kpow within the docker container.
The JVM provides an environment variable called JAVA_TOOL_OPTIONS
that can be used in place of system properties. We use this the thread the JAAS config to Docker.
ENVIRONMENT_NAME=Trade Book (Staging)
BOOTSTRAP=kafka-1:19092,kafka-2:19093,kafka-3:19094
# more docker environment file parameters
AUTH_PROVIDER_TYPE=jetty
JAVA_TOOL_OPTIONS=-Djava.security.auth.login.config=/opt/kpow/jaas/ldap-jaas.conf
When starting the docker container you will see logging output similar to:
Picked up JAVA_TOOL_OPTIONS: -Djava.security.auth.login.config=/path/to/jaas.conf
Configure LDAPS
In your JAAS configuration file set useLdaps="true"
and ensure port
is set to the LDAPS port of your LDAP server.
Providing Custom Certificates for LDAPS SSL
Kpow uses certificates provided in the default JVM truststore to make SSL connections for LDAPS.
To use custom certificates for LDAPS, provide them in a truststore and override the JVM default truststore with the following JVM parameter on startup.
-Djavax.net.ssl.trustStore=/opt/kpow/jaas/ldaps/client.jks -Djavax.net.ssl.trustStorePassword=secret-password -Djavax.net.ssl.trustStoreType=JKS -Djava.security.auth.login.config=/opt/kpow/jaas/ldaps-jaas.conf
To alter JVM startup parameters on startup when using the Kpow Docker container, set the same using the JAVA_TOOL_OPTIONS
environment variable.
Encrypt the trustStorePassword
Optionally encrypt the trustStorePassword Java parameter with Kpow Secure.
As with all Kpow Secure encryption, you will also need to set a corresponding KPOW_SECURE_KEY
or KPOW_SECURE_KEY_LOCATION
environment variable.
JAVA_TOOL_OPTIONS=-Djavax.net.ssl.trustStore=/opt/kpow/jaas/ldaps/client.jks -Djavax.net.ssl.trustStorePassword=AES:ARClD4Hz3A2VpdCGqZArl/OglnIawMHRzW0cVjraODxIeg== -Djavax.net.ssl.trustStoreType=JKS -Djava.security.auth.login.config=/opt/kpow/jaas/ldaps-jaas.conf
Debug Kpow LDAP
To enable debug logging of LdapLoginModule authentication you must:
- Set
debug=true
in your JAAS configuration file - Turn on Kpow debug-level application logs with a custom logback configuration file
- Enable Jetty IGNORE level logs to debug some LDAP connection errors
Enable JAAS Debug
To debug JAAS LDAP connections, first add debug="true"
to your config:
kpow {
io.kpow.jaas.spi.LdapLoginModule required
debug="true"
...
...
Enable Kpow Application Debug Logs
Turn on Jetty JAAS debug-level logging, see Application logs for example configuration that contains Jetty JAAS debug settings.
Enable Jetty IGNORED logs
To debug LDAP connection errors, enable Jetty IGNORE level logs by starting Kpow with the following Java system variable:
-Dorg.eclipse.jetty.util.log.IGNORED=true
Debug Log Examples
Once configured you will find debug log lines in your application logs that provide insight into how the LdapLoginModule is operating.
Successful Login Debug Logs
03:37:47.106 DEBUG [qtp1108191595-67] o.e.j.s.a.FormAuthenticator – challenge node0fdklcoqpau3d142sjx5jkowtm0->/login
03:37:52.628 DEBUG [qtp1108191595-70] io.kpow.jaas.spi.LdapLoginModule – Searching for user jdoe with filter: '(&(objectClass={0})({1}={2}))' from base dn: OU=Users,DC=example,DC=com
03:37:52.645 DEBUG [qtp1108191595-70] io.kpow.jaas.spi.LdapLoginModule – Found user?: true
03:37:52.647 INFO [qtp1108191595-70] io.kpow.jaas.spi.LdapLoginModule – Attempting authentication: cn=Jane Doe,ou=Users,dc=example,dc=com
03:37:52.658 DEBUG [qtp1108191595-70] io.kpow.jaas.spi.LdapLoginModule – Found user roles?: true
03:37:52.666 DEBUG [qtp1108191595-70] o.e.j.s.a.LoginAuthenticator – renew node0fdklcoqpau3d142sjx5jkowtm0->node019y3iaulf0v0o1ouj43dadrlbf1
03:37:52.669 DEBUG [qtp1108191595-70] o.e.j.s.a.FormAuthenticator – jsecuritycheck jdoe DefaultUserIdentity('jdoe')
03:37:52.672 DEBUG [qtp1108191595-70] o.e.j.s.a.FormAuthenticator – authenticated Form{User,FORM,DefaultUserIdentity('jdoe')}->http://localhost:3000/
03:37:52.683 DEBUG [qtp1108191595-69] o.e.j.s.a.FormAuthenticator – Restoring original method GET for http://localhost:3000/ with method GET
03:37:52.684 DEBUG [qtp1108191595-69] o.e.j.s.a.FormAuthenticator – auth retry SessionAuthentication@43aea01d{-,DefaultUserIdentity('jdoe')}->http://localhost:3000/
03:37:52.687 DEBUG [qtp1108191595-69] o.e.j.s.a.FormAuthenticator – auth SessionAuthentication@43aea01d{-,DefaultUserIdentity('jdoe')}
03:37:52.773 DEBUG [qtp1108191595-68] o.e.j.s.a.FormAuthenticator – auth SessionAuthentication@43aea01d{-,DefaultUserIdentity('jdoe')}
03:37:53.577 DEBUG [qtp1108191595-64] o.e.j.s.a.FormAuthenticator – auth SessionAuthentication@43aea01d{-,DefaultUserIdentity('jdoe')}
03:37:53.647 INFO [pool-5-thread-1] operatr.server.query-handlers – New WS connection for client-id db99106b-937b-4775-8f40-2956fd7f5cf8
03:37:54.029 DEBUG [qtp1108191595-67] o.e.j.s.a.FormAuthenticator – auth SessionAuthentication@43aea01d{-,DefaultUserIdentity('jdoe')}
Invalid password debug logs
03:38:11.399 DEBUG [qtp1108191595-67] o.e.j.s.a.FormAuthenticator – challenge node017r30mvaf9l6ngu28a6rgqndd2->/login
03:38:16.377 DEBUG [qtp1108191595-67] io.kpow.jaas.spi.LdapLoginModule – Searching for user jdoe with filter: '(&(objectClass={0})({1}={2}))' from base dn: OU=Users,DC=example,DC=com
03:38:16.382 DEBUG [qtp1108191595-67] io.kpow.jaas.spi.LdapLoginModule – Found user?: true
03:38:16.382 INFO [qtp1108191595-67] io.kpow.jaas.spi.LdapLoginModule – Attempting authentication: cn=Jane Doe,ou=Users,dc=example,dc=com
03:38:16.429 DEBUG [qtp1108191595-67] o.e.jetty.jaas.JAASLoginService – Login failed
javax.security.auth.login.FailedLoginException: [LDAP: error code 49 - INVALID_CREDENTIALS: Bind failed: ERR_229 Cannot authenticate user cn=Jane Doe,ou=Users,dc=example,dc=com]
at io.kpow.jaas.spi.LdapLoginModule.bindingLogin(LdapLoginModule.java:543)
at io.kpow.jaas.spi.LdapLoginModule.login(LdapLoginModule.java:433)
at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:747)
<snip>
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:934)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1078)
at java.base/java.lang.Thread.run(Thread.java:829)
03:38:16.429 DEBUG [qtp1108191595-67] o.e.j.s.a.FormAuthenticator – jsecuritycheck jdoe null
03:38:16.429 DEBUG [qtp1108191595-67] o.e.j.s.a.FormAuthenticator – Form authentication FAILED for jdoe
User not found debug logs
03:41:35.346 DEBUG [qtp437783899-69] o.e.j.s.a.FormAuthenticator – challenge node01oops3xzje0ha1s691bng8tnck0->/login
03:41:41.323 DEBUG [qtp437783899-68] io.kpow.jaas.spi.LdapLoginModule – Searching for user jdoe with filter: '(&(objectClass={0})({1}={2}))' from base dn: OU=User,DC=example,DC=com
03:41:41.337 DEBUG [qtp437783899-68] io.kpow.jaas.spi.LdapLoginModule – Found user?: false
03:41:41.342 DEBUG [qtp437783899-68] o.e.jetty.jaas.JAASLoginService – Login failed
javax.security.auth.login.FailedLoginException: User not found.
at io.kpow.jaas.spi.LdapLoginModule.findUser(LdapLoginModule.java:587)
<snip>
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1078)
at java.base/java.lang.Thread.run(Thread.java:829)
03:41:41.342 DEBUG [qtp437783899-68] o.e.j.s.a.FormAuthenticator – jsecuritycheck jdoe null
03:41:41.344 DEBUG [qtp437783899-68] o.e.j.s.a.FormAuthenticator – Form authentication FAILED for jdoe
03:41:41.345 DEBUG [qtp437783899-68] o.e.j.s.a.FormAuthenticator – auth failed jdoe->/login-retry
If you encounter unexpected 'User Not Found' errors, it is likely that you have the wrong user parameters in your JAAS configuration, check these:
userBaseDn="OU=Users,DC=example,DC=com"
userRdnAttribute="uid"
userIdAttribute="cn"
userPasswordAttribute="userPassword"
userObjectClass="inetOrgPerson"
Those parameters depend on your LDAP structure and vary from organisation to organisation.
User experience
When configured your users will be prompted to authenticate on each new browser session.