Laminas authentication using lmcuser package with custom db adaper

My Zendframework2 application is working fine in the php 7.4 and i have to update it to support php 8.1 and for that i am migrating zf2 to laminas. It was zfcuser implemented in the ZF2. Currently i am replacing zfcuser with lmcuser package in laminas and in the custom authentication getting error in this line

$result = $adapter->prepareForAuthentication($this->getRequest());  

and after commenting this line getting authentication code 0 means it is failing.

my authentication method is this

public function authenticateAction() {
        if ($this->lmcUserAuthentication()->hasIdentity()) {
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
        }
        $adapter = $this->lmcUserAuthentication()->getAuthAdapter();
        
        $redirect = $this->params()->fromPost('redirect', $this->params()->fromQuery('redirect', false));
        
            $result = $adapter->prepareForAuthentication($this->getRequest());
        
        // Return early if an adapter returned a response
        if ($result instanceof Response) {
            return $result;
        }

        $auth = $this->lmcUserAuthentication()->getAuthService()->authenticate($adapter);
        

i checked adapter, request data and authservice using var_dump, all are having data.

getting error Call to a member function get() on null in Authentication/Adapter/Db.php on

$this->setOptions($this->getServiceManager()->get('lmcuser_module_options')); 

line

error is in

$this->getServiceManager()->get('lmcuser_module_options') c

ode Db.php file look like the below

public function preprocessCredential($credential) {
        $processor = $this->getCredentialPreprocessor();
        if (is_callable($processor)) {
            return $processor($credential);
        }
        return $credential;
    }

    /**
     * getMapper
     *
     * @return UserMapperInterface
     */
    public function getMapper() {
        if (null === $this->mapper) {
            $this->mapper = $this->getServiceManager()->get('lmcuser_user_mapper');
        }

        return $this->mapper;
    }

    /**
     * setMapper
     *
     * @param UserMapperInterface $mapper
     * @return Db
     */
    public function setMapper(UserInterface $mapper) {
        $this->mapper = $mapper;
        return $this;
    }

    /**
     * Get credentialPreprocessor.
     *
     * @return \callable
     */
    public function getCredentialPreprocessor() {
        return $this->credentialPreprocessor;
    }

    /**
     * Set credentialPreprocessor.
     *
     * @param $credentialPreprocessor the value to be set
     */
    public function setCredentialPreprocessor($credentialPreprocessor) {
        $this->credentialPreprocessor = $credentialPreprocessor;
        return $this;
    }

    /**
     * Retrieve service manager instance
     *
     * @return ServiceManager
     */
    public function getServiceManager() {
        return $this->serviceManager;
    }

    /**
     * Set service manager instance
     *
     * @param ServiceManager $locator
     * @return void
     */
    public function setServiceManager(ContainerInterface $serviceManager)
    {
        $this->serviceManager = $serviceManager;
    }

    /**
     * @param AuthenticationOptionsInterface $options
     */
    public function setOptions(AuthenticationOptionsInterface $options) {
        $this->options = $options;
    }

    /**
     * @return AuthenticationOptionsInterface
     */
    public function getOptions() {
        if ($this->options === null) {
        
            $this->setOptions($this->getServiceManager()->get('lmcuser_module_options'));
        }
        return $this->options;
    }

lmcuser_module_option configured in the module.config.php file like this

'service_manager' => [
            'factories' => [
                'Router' => 'Laminas\Router\Http\HttpRouterFactory',
                'ViewHelperManager' => 'Laminas\View\HelperPluginManagerFactory',
                'LmcUser\Authentication\Adapter\AdapterChain' => 'LmcUser\Factory\Authentication\Adapter\AdapterChainFactory',
                // 'LmcUser\Authentication\Adapter\AdapterChain' => LmcUser\Authentication\Adapter\AdapterChainServiceFactory::class,
                'LmcUser\Authentication\Adapter\Chain' => 'LmcUser\Factory\Authentication\Adapter\ChainFactory',
                'LmcUser\Service\User' => 'LmcUser\Factory\UserFactory',
                \LmcUser\Authentication\AuthenticationService::class => function($container) {
                    return new \LmcUser\Authentication\AuthenticationService(
                        $container->get('lmcuser_auth_adapter_chain'),
                        $container->get('lmcuser_auth_storage')
                    );
                },
                'lmcuser_module_options' => \LmcUser\Factory\ModuleOptionsFactory::class,
                'lmcuser_auth_adapter_chain' => function($container) {
                    return new \LmcUser\Authentication\Adapter\AdapterChain(); // Adjust according to your setup
                },
                'lmcuser_auth_storage' => function($container) {
                    return new \Laminas\Authentication\Storage\Session(); // Adjust according to your setup
                },
                LmcUser\Options\UserControllerOptionsInterface::class => \LmcUser\Factory\Options\UserControllerOptionsFactory::class,
                'Backend\Authentication\Adapter\Db' => function (ContainerInterface $container) {
                    $dbAdapter = new \Backend\Authentication\Adapter\Db();
                    $dbAdapter->setServiceManager($container);
                    return $dbAdapter;
                },
            
            ],
            'aliases' => [
                'lmcuser_auth_service' => \LmcUser\Authentication\AuthenticationService::class,
                UserControllerOptionsInterface::class => ModuleOptions::class,
            ],
        ],
    ),

Can anybody help me to get resolved this issue?

Check:

It appears to be null. Not real sure why they are injecting a service manager instance there anyway. I would tend to avoid that.

Just dump that and see if its null.

@Praveen_Maurya

Can you provide more details on the errors you are getting? Like a stack trace?

And details on the custom adapter as well?

LmcUser is supposed to be a drop-in replacement for ZfcUser and should work after you migrated your code to use the LmcUser namespace instead of ZfcUser.

The class \LmcUser\Authentication\AuthenticationService does not exist therefore any attempt to create this service will fail.

And I am not sure I understand why you are overriding most of the service manager configuration for LmcUser.

LmcUser provides an adapter (LmcUser\Authentication\Adapter\AdapterChain) that implements the Laminas\Authentication\Adapter\AdapterInterface which, in turns, uses a chain of authentication adapters.

You can specify your own custom chainable authentication adapter via the module option ‘auth_adapters’:

'auth_adapters' => [100 => YourCustomAdapter::class];

And add a factory for your YourCustomAdapter somewhere in your code. And make sure that your adapter either extends LmcUser\Authentication\Adapter\Adapter\AbstractAdapter or implement the LmcUser\Authentication\Adapter\ChainableAdapter interface.

If, instead, you create your own adapter that replaces AdapterChain entirely, then it must implement that same methods as AdapterChain for it to work within LmcUser and override the factories.

Do you also need to have a custom storage to hold the authenticated identity? LmcUser creates a \Laminas\Authentication\AuthenticationService using the LmcUser\Authentication\Storage\Db class which stores the authenticated identity in the session.

If you need more help, join the LM-Commons Slack. There is a channel for LmcUser.