Last active 1729618115

An example of creating a composite adapter for Apigility

Revision 4203e9512ddde6cc4e75b8645cf22397f3dc18de

CompositeAdapter.php Raw
1<?php
2use Zend\Http\Request;
3use Zend\Http\Response;;
4use ZF\MvcAuth\Authentication\AdapterInterface;
5use ZF\MvcAuth\Identity\IdentityInterface;
6use ZF\MvcAuth\MvcAuthEvent;
7
8class CompositeAdapter implements AdapterInterface
9{
10 private $adapters = [];
11
12 private $matched;
13
14 public function attach(AdapterInterface $adapter)
15 {
16 if (in_array($adapter, $this->adapters, true)) {
17 return;
18 }
19
20 $this->adapters[] = $adapter;
21 }
22
23 public function provides()
24 {
25 return array_reduce($this->adapters, function ($carry, $adapter) {
26 $provides = array_merge($carry, $adapter->provides());
27 return array_unique($provides);
28 }, []);
29 }
30
31 public function matches($type)
32 {
33 $this->matched = null;
34
35 foreach ($this->adapters as $adapter) {
36 $match = $adapter->matches($type);
37 if ($match) {
38 $this->matched = $adapter;
39 return true;
40 }
41 }
42
43 return false;
44 }
45
46 public function getTypeFromRequest(Request $request)
47 {
48 foreach ($this->adapters as $adapter) {
49 $type = $adapter->getTypeFromRequest($request);
50 if (false !== $type) {
51 return $type;
52 }
53 }
54 return false;
55 }
56
57 public function preAuth(Request $request, Response $response)
58 {
59 foreach ($this->adapters as $adapter) {
60 $result = $adapter->preAuth($request, $response);
61 if ($result instanceof Response) {
62 return $result;
63 }
64 }
65 }
66
67 public function authenticate(Request $request, Response $response, MvcAuthEvent $mvcAuthEvent)
68 {
69 if (! $this->matched) {
70 return false;
71 }
72
73 // Reset $matched so that subsequent calls fail
74 $adapter = $this->matched;
75 $this->matched = null;
76
77 return $adapter->authenticate($request, $response, $mvcAuthEvent);
78 }
79}
CompositeAdapterDelegatorFactory.php Raw
1<?php
2
3use Zend\ServiceManager\DelegatorFactoryInterface;
4use Zend\ServiceManager\ServiceLocatorInterface;
5
6/**
7 * Delegator factory for adding the CompositeAdapter.
8 *
9 * This delegator factory assumes that you've registered the CompositeAdapter
10 * as the service 'CompositeAdapter'.
11 *
12 * Attach it to the DefaultAuthenticationListener using:
13 *
14 * ```php
15 * 'service_manager' => array(
16 * 'delegators' => array(
17 * 'ZF\MvcAuth\Authentication\DefaultAuthenticationListener' => array(
18 * 'CompositeAdapterDelegatorFactory',
19 * ),
20 * ),
21 * ),
22 * ```
23 */
24class CompositeAdapterDelegatorFactory implements DelegatorFactoryInterface
25{
26 public function createDelegatorWithName(
27 ServiceLocatorInterface $services,
28 $name,
29 $requestedName,
30 $callback
31 ) {
32 $listener = $callback();
33
34 $composite = $services->get('CompositeAdapter');
35 $listener->attach($composite);
36 return $listener;
37 }
38}
CompositeAdapterFactory.php Raw
1<?php
2use ZF\MvcAuth\Factory\AuthenticationHttpAdapterFactory;
3use ZF\MvcAuth\Factory\AuthenticationOAuth2AdapterFactory;
4
5class CompositeAdapterFactory
6{
7 public function __invoke($services)
8 {
9 $config = $services->get('Config');
10 $adapters = [];
11
12 /*
13 * You could put the key somewhere else. The idea, though, is that each
14 * named adapter matches a key under zf-mvc-auth.authentication.adapters. The
15 * primary problem with this approach is that you'll get two instances
16 * for adapters you attach to the composite adapter. One alternative is
17 * to use the approach in ZF\MvcAuth\Factory\AuthenticationAdapterDelegatorFactory
18 * and define the configuration for the attached adapters within this
19 * array, and instantiate them here only. Of course, that means you can
20 * only configure those adapters manually.
21 */
22 if (isset($config['zf-mvc-auth']['authentication']['composite'])
23 && is_array($config['zf-mvc-auth']['authentication']['composite'])
24 ) {
25 $adapters = $config['zf-mvc-auth']['authentication']['composite'];
26 }
27
28 $composite = new CompositeAdapter();
29
30 foreach ($adapters as $adapterName) {
31 $adapter = $this->getAdapter(
32 $adapterName,
33 $config['zf-mvc-auth']['authentication']['adapters'],
34 $services
35 );
36 if (! $adapter) {
37 continue;
38 }
39 $composite->attach($adapter);
40 }
41
42 return $composite;
43 }
44
45 private function getAdapter($adapterName, array $config, $services)
46 {
47 if (! isset $config[$adapterName]
48 || ! isset($config[$adapterName]['adapter'])
49 || ! is_string($config[$adapterName]['adapter'])
50 ) {
51 return false;
52 }
53
54 $config = $config[$adapterName];
55 switch ($config['adapter']) {
56 case 'ZF\MvcAuth\Authentication\HttpAdapter':
57 return AuthenticationHttpAdapterFactory::factory($adapterName, $config, $services);
58 case 'ZF\MvcAuth\Authentication\OAuth2Adapter':
59 return AuthenticationOAuth2AdapterFactory::factory($adapterName, $config, $services);
60 default:
61 return false;
62 }
63 }
64}