Keycloak in Docker container and SSSD User Federation, Failed authentication: java.lang.NullPointerException

Hi,

I have been following Keycloak docs about adding an SSSD User Federation provider instead of using AD/LDAP provider.

  • OS: RHEL 7.6
  • Keycloak version: 11.0.2 (Docker)
  • FreeIPA: freeipa-server:centos-8
  • Docker: 19.03.7

Dockerfile

To achieve this in Docker, I installed jna and libunix-dbus-java-0.8.0-1.fc24.x86_64. Since RHEL UBI doesnt have jna in its repo, I added the centos8 repos and installed jna from those repos instead:

RUN microdnf update -y && microdnf install -y glibc-langpack-en gzip hostname java-11-openjdk-headless openssl tar which jna  && microdnf clean all 
RUN rpm -ivh /tmp/libunix-dbus-java-0.8.0-1.fc24.x86_64.rpm

FreeIPA

On the server I installed sssd-dbus and sssd-tools for debugging and started FreeIPA Server using:

docker run --name freeipa-server-container -it 
-h server.freeipa.local 
-e PASSWORD=password -
v /sys/fs/cgroup:/sys/fs/cgroup:ro 
--sysctl net.ipv6.conf.lo.disable_ipv6=0 
-v /var/lib/ipa-data:/data:Z 
10.242.0.74/library/freeipa/freeipa-server:centos-8

SSSD

Enrolled my server to the domain and ran federation-sssd-setup.sh on the host to configure /etc/sssd/sssd.conf:

[domain/freeipa.local]

cache_credentials = True
krb5_store_password_if_offline = True
ipa_domain = freeipa.local
id_provider = ipa
auth_provider = ipa
access_provider = ipa
ldap_tls_cacert = /etc/ipa/ca.crt
ldap_user_extra_attrs = mail:mail, sn:sn, givenname:givenname, telephoneNumber:telephoneNumber
ipa_hostname = dockerhost.mydomain
chpass_provider = ipa
ipa_server = _srv_, server.freeipa.local
dns_discovery_domain = freeipa.local
[sssd]
services = nss, sudo, pam, ssh, ifp
debug_level=6 

domains = freeipa.local
[nss]
homedir_substring = /home

[pam]

[ifp]
allowed_uids = root
user_attributes = +mail, +telephoneNumber, +givenname, +sn

And /etc/pam.d/keycloak:

  auth        required   pam_sss.so 
  account     required   pam_sss.so

Adding user

# ipa user-add testuser --first=test --last=testuser --email=testuser@mydomain.com --phone=042424242 --street="Testing street" --city="Testing city" --state="Testing State" --postalcode=0000000000 --password

Testing sssd-dbus:

# sssctl user-checks testuser -s keycloak
user: testuser
action: acct
service: keycloak

SSSD nss user lookup result:
 - user name: testuser
 - user id: 1856600005
 - group id: 1856600005
 - gecos: test testuser
 - home directory: /home/testuser
 - shell: /bin/sh

SSSD InfoPipe user lookup result:
 - name: testuser
 - uidNumber: 1856600005
 - gidNumber: 1856600005
 - gecos: test testuser
 - homeDirectory: /home/testuser
 - loginShell: /bin/sh

testing pam_acct_mgmt

pam_acct_mgmt: Success

PAM Environment:
 - no env -

Debus send

# dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe /org/freedesktop/sssd/infopipe org.freedesktop.sssd.infopipe.GetUserGroups string:testuser
method return time=1603972476.282837 sender=:1.12056883 -> destination=:1.12057120 serial=34 reply_serial=2
   array [
      string "ipausers"
   ]

Keycloak

Startup

docker run -d --name keycloak \
-v /var/run/dbus:/var/run/dbus:ro \
-v /etc/sssd/sssd.conf:/etc/sssd/sssd.conf:ro \
-v /etc/pam.d/keycloak:/etc/pam.d/keycloak:ro \
-u root -p 8280:8080 \
-l traefik.enable="true" \
-l traefik.http.routers.keycloak-http.entrypoints="http" \
-l traefik.http.routers.keycloak-http.rule="PathPrefix(\`/auth\`)" \
-l traefik.http.routers.keycloak-https.entrypoints="https" \
-l traefik.http.routers.keycloak-https.tls="true" \
-l traefik.http.routers.keycloak-https.rule="PathPrefix(\`/auth\`)" \
-e KEYCLOAK_USER=admin \
-e KEYCLOAK_PASSWORD=password \
-e PROXY_ADDRESS_FORWARDING=true \
myregistry/library/jboss/keycloaktest:11.0.2

The SSSD provider shows up when I launch the admin console, I am able to configure and enable it. However, when trying to log into a web app using Keycloak (this works with ldap provider) I get the following stack trace:

11:34:00,944 WARN  [org.keycloak.services] (default task-1) KC-SERVICES0013: Failed authentication: java.lang.NullPointerException
	at org.keycloak.federation.sssd.impl.PAMAuthenticator.authenticate(PAMAuthenticator.java:58)
	at org.keycloak.federation.sssd.SSSDFederationProvider.isValid(SSSDFederationProvider.java:182)
	at org.keycloak.credential.UserCredentialStoreManager.validate(UserCredentialStoreManager.java:187)
	at org.keycloak.credential.UserCredentialStoreManager.isValid(UserCredentialStoreManager.java:168)
	at org.keycloak.credential.UserCredentialStoreManager.isValid(UserCredentialStoreManager.java:112)
	at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.validatePassword(AbstractUsernameFormAuthenticator.java:199)
	at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.validatePassword(AbstractUsernameFormAuthenticator.java:188)
	at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.validateUserAndPassword(AbstractUsernameFormAuthenticator.java:128)
	at org.keycloak.authentication.authenticators.browser.UsernamePasswordForm.validateForm(UsernamePasswordForm.java:55)
	at org.keycloak.authentication.authenticators.browser.UsernamePasswordForm.action(UsernamePasswordForm.java:48)
	at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:160)
	at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:938)
	at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:311)
	at org.keycloak.services.resources.LoginActionsService.processAuthentication(LoginActionsService.java:282)
	at org.keycloak.services.resources.LoginActionsService.authenticate(LoginActionsService.java:266)
	at org.keycloak.services.resources.LoginActionsService.authenticateForm(LoginActionsService.java:339)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:138)
	at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:543)
	at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:432)
	at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:393)
	at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
	at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:395)
	at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:364)
	at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:150)
	at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:104)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:440)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135)
	at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
	at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:138)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:215)
	at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:245)
	at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:61)
	at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
	at org.keycloak.provider.wildfly.WildFlyRequestFilter.lambda$doFilter$0(WildFlyRequestFilter.java:41)
	at org.keycloak.services.filters.AbstractRequestFilter.filter(AbstractRequestFilter.java:43)
	at org.keycloak.provider.wildfly.WildFlyRequestFilter.doFilter(WildFlyRequestFilter.java:39)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
	at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:370)
	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
	at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
	at java.lang.Thread.run(Thread.java:748)

11:34:00,945 WARN  [org.keycloak.events] (default task-1) type=LOGIN_ERROR, realmId=myrealm, clientId=myclient, 
userId=null, ipAddress=10.10.10.55, error=invalid_user_credentials, auth_method=openid-connect, auth_type=code, 
redirect_uri=https://dockerhost.mydomain/myclient/auth, code_id=ac228c05-36ba-4b52-a6aa-cdd3051aaab3, username=testuser, authSessionParentId=ac228c05-36ba-4b52-a6aa-cdd3051aaab3, authSessionTabId=Vv4GWH_8664

Any clue why this is happening? The user is cached in keycloak and has correct group membership, just as in FreeIPA.

Where you able to figure out what the issue is. I am having the same errors only with a way newer stack.