Expressive 2 - How to implementing route specific authentication method (using multiple AuthenticationService)?


my goal is to use multiple “Zend\Authentication\AuthenticationService” implementations in one Zend Expresse application.

I have one module ("Api) for handling REST API requests and another module (Frontend) for providing a UI.

In the “Api” module I want to use "Basic Aut"h Authentication like this: (from the docs)

return [
        'aliases' => [
            // Change the alias value for Authentication adapter and
            // UserRepository adapter
            AuthenticationInterface::class => Adapter\BasicAccess::class,
            UserRepositoryInterface::class => UserRepository\Htpasswd::class,
        'factories' => [
            AuthenticationMiddleware::class   => AuthenticationMiddlewareFactory::class,
            Adapter\BasicAccess::class        => Adapter\BasicAccessFactory::class,
            UserRepository\Htpasswd::class    => UserRepository\HtpasswdFactory::class,
	UserRepository\PdoDatabase::class => UserRepository\PdoDatabaseFactory::class

In the Frontend (UI) module the authentication should be via normal form POST data (username, password) and with a session.

Both work (separated), but NOT together,

In the config (ConfigProvider) of each module I can assign an"AuthenticationService::class" implementation factory. But only (excactly) 1 Implementation for the whole application. (because all ConfigProvider are merged; last ConfigProvider with the Factory overwrites all other before).

My first appoach was to implement an abstract factory to create the various AuthenticationService, but in the factory I need the request to decide which one, but the requesr is not available at htis point (using superglobals is NOT a solution). :wink:

Is there a way to solve this?

I have this exact problem myself. I too tried researching the AbstractFactory approach, but hit the same problem - how do I instruct the AbstractFactory to select the appropriate AuthenticationInterface implementation.

I feel like I’m missing something obvious!

Are the two authentication approaches mutually exclusive or do they act in
a chain, like with a fallback?

Marco Pivetta

I my case (sorry to hijack @beitsolutions!) I want one authentication method for one set of routes, and another authentication method for a different set of routes. As @beitsolutions pointed out, because only one alias can be mapped to the AuthenticationInterface::class, only the last loaded config gets to decide which Authentication method is used across all routes.

@JalfResi no problem

@ocramius In my case it is the same, I want to load as less classes/files as I can, so the 2 authentication variants exclude each other (also because of the possible security issues).

My next approch will be to find the point in the zend auth way to intercept and copy (bad way) the Zend classes (because all methods and properties are PRIVATE) and implement a second athentication…

Mybey there is a better way :slight_smile: