NPE in ApiServlet.skip2FAcheckForUser on SAML login when 2FA is disabled (4.22.0.0)
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 2/5
- Tempo estimado
- 1-3 horas
- Facilidade para iniciantes
- 78/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Stack de tecnologia
- java
- Domínio
- api, authentication, backend
Direção de pesquisa
Comece em ApiServlet.java na linha 512 e inspecione como skip2FAcheckForUser lê o atributo de sessão 2FAuthenticated. Em seguida, rastreie SAML2LoginAPIAuthenticatorCmd para comparar a configuração da sessão com o fluxo de login local. Reproduza com SAML2 habilitado e ambas as configurações de 2FA desabilitadas; está concluído quando a solicitação de API subsequente for bem-sucedida sem a NullPointerException e o usuário chegar ao painel.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
problem
COMPONENT NAME
API, SAML
SUMMARY
Every API request issued after a successful samlSso callback throws a NullPointerException in ApiServlet.skip2FAcheckForUser, because session.getAttribute("2FAuthenticated") returns null and is unboxed directly to boolean. The SAML login flow does not set this session attribute, and the 2FA-disabled global settings are not consulted before the unboxing.
Local username/password login is unaffected — only the SAML path triggers the NPE.
STEPS TO REPRODUCE
- Enable SAML2 plugin and configure an IdP (Keycloak in our case).
- Ensure
enable.user.2fa=falseandmandate.user.2fa=false. - Authorize a CloudStack user for SAML via
authorizeSamlSso. - Click "Login with SSO" → authenticate at IdP → redirected back to
/client/api?command=samlSso. - Browser immediately fires follow-up API call (e.g.
listIdps,login, etc.).
EXPECTED RESULTS
The follow-up API request completes; user lands on the dashboard. A null value for the 2FAuthenticated session attribute should be treated as "2FA not required / not completed" rather than dereferenced as a boolean.
ACTUAL RESULTS
Use cannot login via SAML:
2026-05-17 10:22:39,650 ERROR [c.c.a.ApiServlet] (qtp1047478056-364:[ctx-50e47dca]) (logid:59e6408b) unknown exception writing api response java.lang.NullPointerException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "javax.servlet.http.HttpSession.getAttribute(String)" is null
at com.cloud.api.ApiServlet.skip2FAcheckForUser(ApiServlet.java:512)
at com.cloud.api.ApiServlet.processRequestInContext(ApiServlet.java:361)
at com.cloud.api.ApiServlet$1.run(ApiServlet.java:193)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext$1.call(DefaultManagedContext.java:56)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext.callWithContext(DefaultManagedContext.java:103)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext.runWithContext(DefaultManagedContext.java:53)
at com.cloud.api.ApiServlet.processRequest(ApiServlet.java:190)
at com.cloud.api.ApiServlet.doPost(ApiServlet.java:149)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
... (Jetty frames truncated)
Client receives the auth failure / error response, lands back on the login screen.
This is my first ticket here, so be gentle please!
versions
4.22.0 on Debian 13.4 via shapeblue
i cloudstack-common 4.22.0.0-shapeblue0 all A common package which contains files which are shared by several CloudStack packages
ii cloudstack-management 4.22.0.0-shapeblue0 all CloudStack server library
ii cloudstack-usage 4.22.0.0-shapeblue0 all CloudStack usage monitor
And just auto installed java 21 (I know the docs says 17, but I haven't been able to downgrade).
ii default-jdk-headless 2:1.21-76 amd64 Standard Java or Java compatible Development Kit (headless)
ii openjdk-21-jdk-headless:amd64 21.0.11+10-1deb13u2 amd64 OpenJDK Development Kit (JDK) (headless)deb13u2 amd64 OpenJDK Java runtime, using Hotspot JIT (headless)
ii openjdk-21-jre-headless:amd64 21.0.11+10-1
CONFIGURATION
- SAML2 plugin enabled (
saml2.enabled=true) - IdP: Keycloak 26.x, realm
lluw, SAML client with dedicateduidmapper (User Property:email) - 2FA disabled globally:
enable.user.2fa=false,mandate.user.2fa=false - Single management server, MySQL backend
The steps to reproduce the bug
- Enable SAML2 plugin and configure an IdP (Keycloak in our case).
- Ensure
enable.user.2fa=falseandmandate.user.2fa=false. - Authorize a CloudStack user for SAML via
authorizeSamlSso. - Click "Login with SSO" → authenticate at IdP → redirected back to
/client/api?command=samlSso.
5 browser response:
<loginresponse>
<errorcode>531</errorcode>
<errortext>
Your authenticated user is not authorized for SAML Single Sign-On, please contact your administrator
</errortext>
</loginresponse>
LOG response
2026-05-17 10:22:39,650 ERROR [c.c.a.ApiServlet] (qtp1047478056-364:[ctx-50e47dca]) (logid:59e6408b) unknown exception writing api response java.lang.NullPointerException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "javax.servlet.http.HttpSession.getAttribute(String)" is null
at com.cloud.api.ApiServlet.skip2FAcheckForUser(ApiServlet.java:512)
at com.cloud.api.ApiServlet.processRequestInContext(ApiServlet.java:361)
at com.cloud.api.ApiServlet$1.run(ApiServlet.java:193)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext$1.call(DefaultManagedContext.java:56)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext.callWithContext(DefaultManagedContext.java:103)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext.runWithContext(DefaultManagedContext.java:53)
at com.cloud.api.ApiServlet.processRequest(ApiServlet.java:190)
at com.cloud.api.ApiServlet.doPost(ApiServlet.java:149)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
... (Jetty frames truncated)
What to do about it?
Expected result
The follow-up API request completes; user lands on the dashboard. A null value for the 2FAuthenticated session attribute should be treated as "2FA not required / not completed" rather than dereferenced as a boolean.
ApiServlet.java:512reads the2FAuthenticatedattribute and unboxes without a null check.- The SAML auth command (
SAML2LoginAPIAuthenticatorCmd) creates the session but does not set2FAuthenticated. - Suggested fix: replace direct unboxing with
Boolean.TRUE.equals(session.getAttribute("2FAuthenticated")), or short-circuit when bothenable.user.2faandmandate.user.2faare false.
- Linguagem predominante
- Java
- Estrelas
- 3.1k
- Forks
- 1.4k
- Merge médio
- 7d 5h
- PRs com merge (30d)
- 28
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de apache/cloudstack
-
create-kubernetes-binaries-iso.sh builds the ISO without setting a volume ID on EL8 based os's Abertabug component:kubernetes
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 88/100
apache/cloudstack#14180 ·
-
bug component:projects component:UI
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 88/100
apache/cloudstack#14070 · 5 comentários ·
-
component:backup
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
apache/cloudstack#14013 ·
-
KVM agent fails to connect to Ceph RBD storage pool after upgrading Ceph client to Tentacle 20.2.4 Abertabug component:ceph
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
apache/cloudstack#13989 · 3 comentários ·
-
component:UI
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
apache/cloudstack#13944 · 3 comentários ·
Todas as issues de apache/cloudstack
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
infinispan/infinispan#18150 ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
-
untriaged
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
opensearch-project/k-NN#3597 ·
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 88/100
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100