wso2 / product-is

Welcome to the WSO2 Identity Server source code! For info on working with the WSO2 Identity Server repository and contributing code, click the link below.
http://wso2.github.io/
Apache License 2.0
748 stars 729 forks source link

Authentication fails when a custom callback_factory is configured #16525

Closed deshankoswatte closed 1 year ago

deshankoswatte commented 1 year ago

Describe the issue:

When you configure a custom callback_factory such as the one that is defined at [1], the authentication fails with a NullPointerException. A sample stack trace would be as follows.

[2023-08-25 12:14:00,776] [fe7b0500-af5e-4899-9087-b75b51454565] ERROR {org.wso2.carbon.user.core.common.AbstractUserStoreManager} - Error occurred while authenticating user: admin java.lang.NullPointerException
    at org.wso2.carbon.user.core.util.UserCoreUtil.getDomainName(UserCoreUtil.java:671)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.getMyDomainName(AbstractUserStoreManager.java:9049)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateInternalWithID(AbstractUserStoreManager.java:10853)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateInternalIterationWithID(AbstractUserStoreManager.java:10665)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.lambda$authenticateWithID$16(AbstractUserStoreManager.java:10641)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateWithID(AbstractUserStoreManager.java:10639)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.lambda$authenticateWithID$15(AbstractUserStoreManager.java:10608)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateWithID(AbstractUserStoreManager.java:10599)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.generateUserStoreChainWithID(AbstractUserStoreManager.java:10729)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateInternalIterationWithID(AbstractUserStoreManager.java:10661)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.lambda$authenticateWithID$16(AbstractUserStoreManager.java:10641)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateWithID(AbstractUserStoreManager.java:10639)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.lambda$authenticateWithID$15(AbstractUserStoreManager.java:10608)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateWithID(AbstractUserStoreManager.java:10599)
    at org.wso2.carbon.identity.application.authenticator.basicauth.BasicAuthenticator.processAuthenticationResponse(BasicAuthenticator.java:501)
    at org.wso2.carbon.identity.application.authentication.framework.AbstractApplicationAuthenticator.process(AbstractApplicationAuthenticator.java:90)
    at org.wso2.carbon.identity.application.authenticator.basicauth.BasicAuthenticator.process(BasicAuthenticator.java:132)
    at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.doAuthentication(DefaultStepHandler.java:528)
    at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handleResponse(DefaultStepHandler.java:497)
    at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handle(DefaultStepHandler.java:189)
    at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.DefaultStepBasedSequenceHandler.handle(DefaultStepBasedSequenceHandler.java:179)
    at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handle(GraphBasedSequenceHandler.java:115)
    at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultAuthenticationRequestHandler.handle(DefaultAuthenticationRequestHandler.java:183)
    at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator.handle(DefaultRequestCoordinator.java:253)
    at org.wso2.carbon.identity.application.authentication.framework.servlet.CommonAuthenticationServlet.doPost(CommonAuthenticationServlet.java:53)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.eclipse.equinox.http.helper.ContextPathServletAdaptor.service(ContextPathServletAdaptor.java:37)
    at org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:128)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:60)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.service(DelegationServlet.java:68)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.wso2.carbon.identity.captcha.filter.CaptchaFilter.doFilter(CaptchaFilter.java:66)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.owasp.csrfguard.CsrfGuardFilter.doFilter(CsrfGuardFilter.java:88)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.wso2.carbon.tomcat.ext.filter.CharacterSetFilter.doFilter(CharacterSetFilter.java:65)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.wso2.carbon.identity.context.rewrite.valve.TenantContextRewriteValve.invoke(TenantContextRewriteValve.java:107)
    at org.wso2.carbon.identity.cors.valve.CORSValve.invoke(CORSValve.java:93)
    at org.wso2.carbon.identity.authz.valve.AuthorizationValve.invoke(AuthorizationValve.java:110)
    at org.wso2.carbon.identity.auth.valve.AuthenticationValve.invoke(AuthenticationValve.java:114)
    at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:101)
    at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:49)
    at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)
    at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:145)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57)
    at org.wso2.carbon.tomcat.ext.valves.RequestEncodingValve.invoke(RequestEncodingValve.java:49)
    at org.wso2.carbon.tomcat.ext.valves.RequestCorrelationIdValve.invoke(RequestCorrelationIdValve.java:126)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:750)

According to the analysis that has been done for [2], this has been working previously in the WSO2 Identity Server version 5.11.0. However, we have recently changed the authenticate method to authenticateWithID in 5.11.0 hence it is reproducible in 5.11.0 as well.

How to reproduce:

Expected behavior:

The realm configuration should be properly retrieved so that it would not result in a NullPointerException.

Environment information (Please complete the following information; remove any unnecessary fields) :

References:

[1] - https://medium.com/@nilasini/user-store-preference-order-per-service-provider-available-from-5-9-0-onwards-bcd7648a485c [2] - https://github.com/wso2/api-manager/issues/2125

UdeshAthukorala commented 1 year ago

This will be fixed in master via: https://github.com/wso2/carbon-kernel/pull/3631

deshankoswatte commented 1 year ago

Unfortunately, the flow has not been tested for the non unique id user stores and if you test the same you will still get an NPE. A sample stack trace would be as follows.

TID: [-1234] [] [2023-09-04 13:08:10,155] [6558c4fa-2275-48cd-b44a-38aedd2ff6d3] ERROR {org.wso2.carbon.user.core.common.AbstractUserStoreManager} - Error occurred while authenticating user: test java.lang.NullPointerException
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.doGetUserList(AbstractUserStoreManager.java:2917)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateInternalWithID(AbstractUserStoreManager.java:10861)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateInternalIterationWithID(AbstractUserStoreManager.java:10665)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.lambda$authenticateWithID$16(AbstractUserStoreManager.java:10641)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateWithID(AbstractUserStoreManager.java:10639)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.lambda$authenticateWithID$15(AbstractUserStoreManager.java:10608)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateWithID(AbstractUserStoreManager.java:10599)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.generateUserStoreChainWithID(AbstractUserStoreManager.java:10729)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateInternalIterationWithID(AbstractUserStoreManager.java:10661)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.lambda$authenticateWithID$16(AbstractUserStoreManager.java:10641)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateWithID(AbstractUserStoreManager.java:10639)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.lambda$authenticateWithID$15(AbstractUserStoreManager.java:10608)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at org.wso2.carbon.user.core.common.AbstractUserStoreManager.authenticateWithID(AbstractUserStoreManager.java:10599)
    at org.wso2.carbon.identity.application.authenticator.basicauth.BasicAuthenticator.processAuthenticationResponse(BasicAuthenticator.java:501)
    at org.wso2.carbon.identity.application.authentication.framework.AbstractApplicationAuthenticator.process(AbstractApplicationAuthenticator.java:90)
    at org.wso2.carbon.identity.application.authenticator.basicauth.BasicAuthenticator.process(BasicAuthenticator.java:132)
    at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.doAuthentication(DefaultStepHandler.java:528)
    at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handleResponse(DefaultStepHandler.java:497)
    at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handle(DefaultStepHandler.java:189)
    at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.DefaultStepBasedSequenceHandler.handle(DefaultStepBasedSequenceHandler.java:179)
    at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handle(GraphBasedSequenceHandler.java:115)
    at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultAuthenticationRequestHandler.handle(DefaultAuthenticationRequestHandler.java:183)
    at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator.handle(DefaultRequestCoordinator.java:253)
    at org.wso2.carbon.identity.application.authentication.framework.servlet.CommonAuthenticationServlet.doPost(CommonAuthenticationServlet.java:53)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.eclipse.equinox.http.helper.ContextPathServletAdaptor.service(ContextPathServletAdaptor.java:37)
    at org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:128)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:60)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.service(DelegationServlet.java:68)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.wso2.carbon.identity.captcha.filter.CaptchaFilter.doFilter(CaptchaFilter.java:66)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.owasp.csrfguard.CsrfGuardFilter.doFilter(CsrfGuardFilter.java:88)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.wso2.carbon.tomcat.ext.filter.CharacterSetFilter.doFilter(CharacterSetFilter.java:65)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.wso2.carbon.identity.context.rewrite.valve.TenantContextRewriteValve.invoke(TenantContextRewriteValve.java:107)
    at org.wso2.carbon.identity.cors.valve.CORSValve.invoke(CORSValve.java:93)
    at org.wso2.carbon.identity.authz.valve.AuthorizationValve.invoke(AuthorizationValve.java:110)
    at org.wso2.carbon.identity.auth.valve.AuthenticationValve.invoke(AuthenticationValve.java:114)
    at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:101)
    at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:49)
    at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)
    at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:145)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57)
    at org.wso2.carbon.tomcat.ext.valves.RequestEncodingValve.invoke(RequestEncodingValve.java:49)
    at org.wso2.carbon.tomcat.ext.valves.RequestCorrelationIdValve.invoke(RequestCorrelationIdValve.java:126)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:829)

We have to fix and test the same as well.