Integrate Persistent ACL for merchant API endpoints
Edit on GitHubThis document describes how to enable Persistent ACL for the Backend API so that merchant users see and change only the data of their merchant, the same way they do in the Merchant Portal.
With the API Platform integration, the Backend API resolves the user behind a Back Office or merchant user token and makes it the acting user of the request. Persistent ACL uses the acting user to filter database queries. After the integration described here, the following applies:
- A merchant user reads and writes the data of the merchant it is assigned to only. Merchant-specific resources like the merchant profile return
404or an empty collection for data of other merchants. - A Back Office user without a merchant is not scoped and reads the data of every merchant, as in the Back Office.
- Requests without an acting user, such as
POST /tokenand public endpoints, are not filtered.
The acting user of a request exists only in the API Platform integration of the Backend API. The legacy Glue infrastructure does not resolve the user behind a token, so Persistent ACL cannot scope legacy Glue resources; they stay unfiltered even after the plugins on this page are registered. Legacy Glue resources are protected by scopes and route rules instead. For details, see Use Backend API authorization scopes and Create protected Backend API endpoints.
Prerequisites
- API Platform and its security are integrated for the Backend API as described in Integrate API Platform and Integrate API Platform security.
- Merchant users can authenticate against the Backend API as described in Authenticate as a merchant user.
- The Persistent ACL rules for merchants are configured. Merchant Portal projects come with them out of the box; see Persistence ACL configuration.
Install the required modules using Composer:
composer require spryker/acl-entity:"^1.18.0" spryker/merchant-user:"^1.10.0" --update-with-dependencies
| MODULE | MINIMUM VERSION | PROVIDES |
|---|---|---|
| spryker/acl-entity | ^1.18.0 | The AclEntityApplicationPlugin for the Glue layer, which enables Persistent ACL in the Backend API application. |
| spryker/merchant-user | ^1.10.0 | The NoCurrentMerchantUserAclEntityDisablerPlugin, which limits the scoping to merchant users. |
1. Enable Persistent ACL in the Backend API application
Persistent ACL is enabled per application. Register the Glue AclEntityApplicationPlugin in the Backend API application:
| PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
|---|---|---|---|
| AclEntityApplicationPlugin | Enables Persistent ACL for the Backend API application. | Spryker\Glue\AclEntity\Plugin\Application |
src/Pyz/Glue/GlueBackendApiApplication/GlueBackendApiApplicationDependencyProvider.php
<?php
namespace Pyz\Glue\GlueBackendApiApplication;
use Spryker\Glue\AclEntity\Plugin\Application\AclEntityApplicationPlugin;
use Spryker\Glue\GlueBackendApiApplication\GlueBackendApiApplicationDependencyProvider as SprykerGlueBackendApiApplicationDependencyProvider;
class GlueBackendApiApplicationDependencyProvider extends SprykerGlueBackendApiApplicationDependencyProvider
{
/**
* @return array<\Spryker\Shared\ApplicationExtension\Dependency\Plugin\ApplicationPluginInterface>
*/
protected function getApplicationPlugins(): array
{
return [
new AclEntityApplicationPlugin(),
];
}
}
The Zed layer ships its own Spryker\Zed\AclEntity\Communication\Plugin\Application\AclEntityApplicationPlugin, which the Back Office and the Merchant Portal register. The Backend API is a Glue application and needs the Glue plugin from the table above.
2. Limit the scoping to merchant users
Persistent ACL filters every query of a request once it is enabled for the application. To keep Back Office users and requests without an acting user unfiltered, register a disabler plugin that turns Persistent ACL off unless the acting user is a merchant user:
| PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
|---|---|---|---|
| NoCurrentMerchantUserAclEntityDisablerPlugin | Disables Persistent ACL when the current request has no acting user or the acting user is not assigned to a merchant. | Spryker\Zed\MerchantUser\Communication\Plugin\AclEntity |
src/Pyz/Zed/AclEntity/AclEntityDependencyProvider.php
<?php
namespace Pyz\Zed\AclEntity;
use Spryker\Zed\AclEntity\AclEntityDependencyProvider as SprykerAclEntityDependencyProvider;
use Spryker\Zed\MerchantUser\Communication\Plugin\AclEntity\NoCurrentMerchantUserAclEntityDisablerPlugin;
class AclEntityDependencyProvider extends SprykerAclEntityDependencyProvider
{
/**
* @return array<\Spryker\Zed\AclEntityExtension\Dependency\Plugin\AclEntityDisablerPluginInterface>
*/
protected function getAclEntityDisablerPlugins(): array
{
return [
new NoCurrentMerchantUserAclEntityDisablerPlugin(),
];
}
}
Disabler plugins are evaluated wherever Persistent ACL is enabled, including the Merchant Portal. There, the acting user is always a merchant user, so the plugin does not change the Merchant Portal behavior. If your project already registers other disabler plugins, keep them in the list.
3. Clear caches
docker/sdk cli console cache:empty-all
- Authenticate as a merchant user and request a resource that is scoped by Persistent ACL, for example,
GET /merchant-profile. Make sure the response contains only the data of the merchant the user is assigned to. - Authenticate as a Back Office user without a merchant and request a resource that reads merchant data, for example,
GET /merchant-profiles/{merchantReference}of several merchants. Make sure every merchant is returned. - Send
POST /tokenwithout anAuthorizationheader. Make sure a token is issued.
Thank you!
For submitting the form