Install the Multi-Factor Authentication Merchant Portal feature
Edit on GitHubThis document describes how to install the Multi-Factor Authentication (MFA) feature for the Merchant Portal.
Prerequisites
FEATURE | VERSION | INSTALLATION GUIDE |
---|---|---|
Marketplace Merchant Portal Core | 202507.0 | Install the Marketplace Merchant Portal Core |
Merchant Portal Agent Assist | 202507.0 | Install the Merchant Portal Agent Assist feature |
Multi-Factor Authentication | 202507.0 | Install the Multi-Factor Authentication feature |
1) Install the required modules
Install the required modules using Composer:
composer require spryker/multi-factor-auth-merchant-portal:"^1.0.0" --update-with-dependencies
Make sure the following modules have been installed:
MODULE | EXPECTED DIRECTORY |
---|---|
MultiFactorAuthMerchantPortal | vendor/spryker/multi-factor-auth-merchant-portal |
2) Set up configuration
Set up the configuration in the following sections.
Configure protected routes and forms for users
You can configure multiple forms on the same page to require MFA.
src/Pyz/Zed/MultiFactorAuth/MultiFactorAuthConfig.php
namespace Pyz\Zed\MultiFactorAuth;
use Spryker\Zed\MultiFactorAuth\MultiFactorAuthConfig as SprykerMultiFactorAuthConfig;
class MultiFactorAuthConfig extends SprykerMultiFactorAuthConfig
{
/**
* Specifications:
* - Returns a list of enabled routes and their corresponding forms for user multi-factor authentication in the following format
* [
* 'routeName' => ['formName'],
* ]
*
* @api
*
* @return array<string, array<string>>
*/
public function getEnabledRoutesAndForms(): array
{
return [
'YOUR_ROUTE_NAME' => ['YOUR_FORM_NAME'],
];
}
}
Configure Back Office ACL access
To allow access to MFA requests for the Back Office login, define a public ACL rule.
config/Shared/config_default.php
$config[AclConstants::ACL_DEFAULT_RULES] = [
[
'bundle' => 'multi-factor-auth-merchant-portal',
'controller' => '*',
'action' => '*',
'type' => 'allow',
],
[
'bundle' => 'agent-security-merchant-portal-gui',
'controller' => '*',
'action' => '*',
'type' => 'allow',
],
];
Configure navigation
Add the MFA setup navigation item to one of the following files:
Merchant Portal: config/Zed/navigation-secondary-merchant-portal.xml
<set-up-multi-factor-auth>
<label>Set up Multi-Factor Authentication</label>
<title>Set up Multi-Factor Authentication</title>
<bundle>multi-factor-auth-merchant-portal</bundle>
<controller>user-management</controller>
<action>set-up</action>
</set-up-multi-factor-auth>
Merchant Agent Portal: config/Zed/navigation-secondary-merchant-portal.xml
<set-up-multi-factor-auth-agent>
<label>Set up Multi-Factor Authentication</label>
<title>Set up Multi-Factor Authentication</title>
<bundle>multi-factor-auth-merchant-portal</bundle>
<controller>agent-user-management</controller>
<action>set-up</action>
</set-up-multi-factor-auth-agent>
Configure whitelisted routes
To allow MFA routes to bypass default security restrictions during login or MFA validation flows in the Merchant Portal, extend the whitelisted route and path patterns in one of the following files:
Merchant Portal: src/Pyz/Zed/SecurityMerchantPortalGui/SecurityMerchantPortalGuiConfig.php
<?php
namespace Pyz\Zed\SecurityMerchantPortalGui;
use Spryker\Zed\SecurityMerchantPortalGui\SecurityMerchantPortalGuiConfig as SprykerSecurityMerchantPortalGuiConfig;
class SecurityMerchantPortalGuiConfig extends SprykerSecurityMerchantPortalGuiConfig
{
/**
* @var string
*/
protected const MERCHANT_PORTAL_ROUTE_PATTERN = '^/((.+)-merchant-portal-gui|multi-factor-auth-merchant-portal/(merchant-user|user-management)|_profiler)/';
/**
* @var string
*/
protected const IGNORABLE_PATH_PATTERN = '^/(security-merchant-portal-gui|multi-factor-auth-merchant-portal|_profiler)';
}
Agent Merchant Portal: src/Pyz/Zed/AgentSecurityMerchantPortalGui/AgentSecurityMerchantPortalGuiConfig.php
<?php
namespace Pyz\Zed\AgentSecurityMerchantPortalGui;
use Spryker\Zed\AgentSecurityMerchantPortalGui\AgentSecurityMerchantPortalGuiConfig as SprykerAgentSecurityMerchantPortalGuiConfig;
class AgentSecurityMerchantPortalGuiConfig extends SprykerAgentSecurityMerchantPortalGuiConfig
{
/**
* @return string
*/
public function getRoutePatternAgentMerchantPortal(): string
{
return '^/(agent(.+)-merchant-portal-gui|multi-factor-auth-merchant-portal/(agent-merchant-user|agent-user-management))(?!agent-security-merchant-portal-gui\/login$)/';
}
/**
* @return string
*/
public function getRoutePatternAgentMerchantPortalLogin(): string
{
return '^/(agent-security-merchant-portal-gui/login|multi-factor-auth-merchant-portal/agent-merchant-user($|/))';
}
}
3) Set up transfer objects
Apply database changes and generate entity and transfer changes:
console transfer:generate
Make sure the following changes have been applied in transfer objects:
TRANSFER | TYPE | EVENT | PATH |
---|---|---|---|
MultiFactorAuth | class | created | src/Generated/Shared/Transfer/MultiFactorAuthTransfer |
MultiFactorAuthCode | class | created | src/Generated/Shared/Transfer/MultiFactorAuthCodeTransfer |
MultiFactorAuthTypesCollection | class | created | src/Generated/Shared/Transfer/MultiFactorAuthTypesCollectionTransfer |
MultiFactorAuthValidationRequest | class | created | src/Generated/Shared/Transfer/MultiFactorAuthValidationRequestTransfer |
MultiFactorAuthValidationResponse | class | created | src/Generated/Shared/Transfer/MultiFactorAuthValidationResponseTransfer |
MultiFactorAuthCriteria | class | created | src/Generated/Shared/Transfer/MultiFactorAuthCriteria |
MultiFactorAuthCodeCriteria | class | created | src/Generated/Shared/Transfer/MultiFactorAuthCodeCriteriaTransfer |
4) Set up behavior
Enable the following behaviors by registering the plugins:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
UserMultiFactorAuthAclEntityConfigurationExpanderPlugin | Provides ACL entity configuration for a merchant user. | Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\AclMerchantPortal | |
PostMerchantUserLoginMultiFactorAuthenticationPlugin | Handles merchant user MFA after a successful login. | Spryker\Zed\SecurityMerchantPortalGui\Communication\Plugin\MultiFactorAuth | |
PostAgentMerchantUserLoginMultiFactorAuthenticationPlugin | Handles agent merchant user MFA after a successful login. | Spryker\Zed\AgentSecurityMerchantPortalGui\Communication\Plugin\MultiFactorAuth | |
MerchantUserMultiFactorAuthenticationHandlerPlugin | Handles merchant user login MFA. | Spryker\Zed\MultiFactorAuth\Communication\Plugin\AuthenticationHandler\MerchantUser | |
MerchantAgentUserMultiFactorAuthenticationHandlerPlugin | Handles agent merchant user login MFA. | Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\AuthenticationHandler\MerchantAgentUser | |
MerchantPortalNavigationItemCollectionFilterPlugin | Controls visibility of the MFA setup option in Merchant Portal navigation menu based on user role and available MFA methods. | Spryker\Zed\MultiFactorAuth\Communication\Plugin\Navigation | |
AgentMerchantPortalNavigationItemCollectionFilterPlugin | Controls visibility of the MFA setup option in Agent Merchant Portal navigation menu based on user role and available MFA methods. | Spryker\Zed\MultiFactorAuth\Communication\Plugin\Navigation | |
MultiFactorAuthenticationMerchantUserSecurityPlugin | Registers merchant user provider. | Spryker\Zed\SecurityMerchantPortalGui\Communication\Plugin\MultiFactorAuth | |
MultiFactorAuthenticationAgentMerchantUserSecurityPlugin | Registers agent merchant user provider. | Spryker\Zed\AgentSecurityMerchantPortalGui\Communication\Plugin\MultiFactorAuth | |
MerchantPortalMultiFactorAuthPluginExpanderPlugin | Expands the list of MFA plugins. | Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\Expander |
Register plugins for Merchant Portal
src/Pyz/Zed/AclMerchantPortal/AclMerchantPortalDependencyProvider.php
namespace Pyz\Zed\AclMerchantPortal;
use Spryker\Zed\AclMerchantPortal\AclMerchantPortalDependencyProvider as SprykerAclMerchantPortalDependencyProvider;
use Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\AclMerchantPortal\UserMultiFactorAuthAclEntityConfigurationExpanderPlugin;
class AclMerchantPortalDependencyProvider extends SprykerAclMerchantPortalDependencyProvider
{
protected function getAclEntityConfigurationExpanderPlugins(): array
{
return [
new UserMultiFactorAuthAclEntityConfigurationExpanderPlugin(),
];
}
}
src/Pyz/Zed/MultiFactorAuth/MultiFactorAuthDependencyProvider.php
namespace Pyz\Zed\MultiFactorAuth;
use Spryker\Zed\MultiFactorAuth\MultiFactorAuthDependencyProvider as SprykerMultiFactorAuthDependencyProvider;
use Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\Expander\MerchantPortalMultiFactorAuthPluginExpanderPlugin;
class MultiFactorAuthDependencyProvider extends SprykerMultiFactorAuthDependencyProvider
{
protected function getMultiFactorAuthPluginExpanderPlugins(): array
{
return [
new MerchantPortalMultiFactorAuthPluginExpanderPlugin(),
];
}
}
src/Pyz/Zed/MultiFactorAuthMerchantPortal/MultiFactorAuthMerchantPortalDependencyProvider.php
namespace Pyz\Zed\MultiFactorAuthMerchantPortal;
use Spryker\Zed\MultiFactorAuth\Communication\Plugin\Factors\Email\UserEmailMultiFactorAuthPlugin;
use Spryker\Zed\MultiFactorAuthMerchantPortal\MultiFactorAuthMerchantPortalDependencyProvider as SprykerMultiFactorAuthMultiFactorAuthMerchantPortalDependencyProvider;
use Spryker\Zed\SecurityMerchantPortalGui\Communication\Plugin\MultiFactorAuth\PostMerchantUserLoginMultiFactorAuthenticationPlugin;
class MultiFactorAuthMerchantPortalDependencyProvider extends SprykerMultiFactorAuthMultiFactorAuthMerchantPortalDependencyProvider
{
protected function getUserMultiFactorAuthPlugins(): array
{
return [
new UserEmailMultiFactorAuthPlugin(),
];
}
protected function getPostLoginMultiFactorAuthenticationPlugins(): array
{
return [
new PostMerchantUserLoginMultiFactorAuthenticationPlugin(),
];
}
}
src/Pyz/Zed/ZedNavigation/ZedNavigationDependencyProvider.php
namespace Pyz\Zed\ZedNavigation;
use Spryker\Zed\ZedNavigation\ZedNavigationDependencyProvider as SprykerZedNavigationDependencyProvider;
use Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\Navigation\MerchantPortalNavigationItemCollectionFilterPlugin;
class ZedNavigationDependencyProvider extends SprykerZedNavigationDependencyProvider
{
protected function getNavigationItemCollectionFilterPlugins(): array
{
return [
// Manages the visibility of the "Set up Multi-Factor Authentication" navigation item in the Merchant Portal UI.
// It determines whether this option should be shown to users by two key checks:
// - Checks if there are any MFA plugin methods registered
// - Verifies if the current user has the Merchant role
new MerchantPortalNavigationItemCollectionFilterPlugin(),
];
}
}
src/Pyz/Zed/SecurityMerchantPortalGui/SecurityMerchantPortalGuiDependencyProvider.php
namespace Pyz\Zed\SecurityMerchantPortalGui;
use Spryker\Zed\SecurityMerchantPortalGui\SecurityMerchantPortalGuiDependencyProvider as SprykerSecurityMerchantPortalGuiDependencyProvider;
use Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\AuthenticationHandler\MerchantUser\MerchantUserMultiFactorAuthenticationHandlerPlugin;
class SecurityMerchantPortalGuiDependencyProvider extends SprykerSecurityMerchantPortalGuiDependencyProvider
{
protected function getMerchantUserAuthenticationHandlerPlugins(): array
{
return [
new MerchantUserMultiFactorAuthenticationHandlerPlugin(),
];
}
}
src/Pyz/Zed/Security/SecurityDependencyProvider.php
namespace Pyz\Zed\Security;
use Spryker\Zed\Security\SecurityDependencyProvider as SprykerSecurityDependencyProvider;
use Spryker\Zed\SecurityMerchantPortalGui\Communication\Plugin\MultiFactorAuth\MultiFactorAuthenticationMerchantUserSecurityPlugin;
class SecurityDependencyProvider extends SprykerSecurityDependencyProvider
{
protected function getSecurityPlugins(): array
{
return [
new MultiFactorAuthenticationMerchantUserSecurityPlugin(),
];
}
}
Register plugins for Agent Merchant Portal
src/Pyz/Zed/AclMerchantPortal/AclMerchantPortalDependencyProvider.php
namespace Pyz\Zed\AclMerchantPortal;
use Spryker\Zed\AclMerchantPortal\AclMerchantPortalDependencyProvider as SprykerAclMerchantPortalDependencyProvider;
use Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\AclMerchantPortal\UserMultiFactorAuthAclEntityConfigurationExpanderPlugin;
class AclMerchantPortalDependencyProvider extends SprykerAclMerchantPortalDependencyProvider
{
protected function getAclEntityConfigurationExpanderPlugins(): array
{
return [
new UserMultiFactorAuthAclEntityConfigurationExpanderPlugin(),
];
}
}
src/Pyz/Zed/MultiFactorAuth/MultiFactorAuthDependencyProvider.php
namespace Pyz\Zed\MultiFactorAuth;
use Spryker\Zed\MultiFactorAuth\MultiFactorAuthDependencyProvider as SprykerMultiFactorAuthDependencyProvider;
use Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\Expander\MerchantPortalMultiFactorAuthPluginExpanderPlugin;
class MultiFactorAuthDependencyProvider extends SprykerMultiFactorAuthDependencyProvider
{
protected function getMultiFactorAuthPluginExpanderPlugins(): array
{
return [
new MerchantPortalMultiFactorAuthPluginExpanderPlugin(),
];
}
}
src/Pyz/Zed/MultiFactorAuthMerchantPortal/MultiFactorAuthMerchantPortalDependencyProvider.php
namespace Pyz\Zed\MultiFactorAuthMerchantPortal;
use Spryker\Zed\MultiFactorAuth\Communication\Plugin\Factors\Email\UserEmailMultiFactorAuthPlugin;
use Spryker\Zed\MultiFactorAuthMerchantPortal\MultiFactorAuthMerchantPortalDependencyProvider as SprykerMultiFactorAuthMultiFactorAuthMerchantPortalDependencyProvider;
use Spryker\Zed\AgentSecurityMerchantPortalGui\Communication\Plugin\MultiFactorAuth\PostAgentMerchantUserLoginMultiFactorAuthenticationPlugin;
class MultiFactorAuthMerchantPortalDependencyProvider extends SprykerMultiFactorAuthMultiFactorAuthMerchantPortalDependencyProvider
{
protected function getUserMultiFactorAuthPlugins(): array
{
return [
new UserEmailMultiFactorAuthPlugin(),
];
}
protected function getPostLoginMultiFactorAuthenticationPlugins(): array
{
return [
new PostAgentMerchantUserLoginMultiFactorAuthenticationPlugin(),
];
}
}
src/Pyz/Zed/AgentSecurityMerchantPortalGui/AgentSecurityMerchantPortalGuiDependencyProvider.php
namespace Pyz\Zed\AgentSecurityMerchantPortalGui;
use Spryker\Zed\AgentSecurityMerchantPortalGui\AgentSecurityMerchantPortalGuiDependencyProvider as SprykerAgentSecurityMerchantPortalGuiDependencyProvider;
use Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\AuthenticationHandler\MerchantAgentUser\MerchantAgentUserMultiFactorAuthenticationHandlerPlugin;
class AgentSecurityMerchantPortalGuiDependencyProvider extends SprykerAgentSecurityMerchantPortalGuiDependencyProvider
{
protected function getMerchantAgentUserAuthenticationHandlerPlugins(): array
{
return [
new MerchantAgentUserMultiFactorAuthenticationHandlerPlugin(),
];
}
}
src/Pyz/Zed/ZedNavigation/ZedNavigationDependencyProvider.php
namespace Pyz\Zed\ZedNavigation;
use Spryker\Zed\ZedNavigation\ZedNavigationDependencyProvider as SprykerZedNavigationDependencyProvider;
use Spryker\Zed\MultiFactorAuthMerchantPortal\Communication\Plugin\Navigation\AgentMerchantPortalNavigationItemCollectionFilterPlugin;
class ZedNavigationDependencyProvider extends SprykerZedNavigationDependencyProvider
{
protected function getNavigationItemCollectionFilterPlugins(): array
{
return [
// Manages the visibility of the "Set up Multi-Factor Authentication" navigation item in the Agent Merchant Portal UI.
// It determines whether this option should be shown to users by two key checks:
// - Checks if there are any MFA plugin methods registered
// - Verifies if the current user has the Merchant Agent role
new AgentMerchantPortalNavigationItemCollectionFilterPlugin(),
];
}
}
src/Pyz/Zed/Security/SecurityDependencyProvider.php
namespace Pyz\Zed\Security;
use Spryker\Zed\Security\SecurityDependencyProvider as SprykerSecurityDependencyProvider;
use Spryker\Zed\AgentSecurityMerchantPortalGui\Communication\Plugin\MultiFactorAuth\MultiFactorAuthenticationAgentMerchantUserSecurityPlugin;
class SecurityDependencyProvider extends SprykerSecurityDependencyProvider
{
protected function getSecurityPlugins(): array
{
return [
new MultiFactorAuthenticationAgentMerchantUserSecurityPlugin(),
];
}
}
7) Set up the frontend
Add the following settings:
tsconfig.mp.json
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"target": "ES2022",
"paths": {
...
"@mp/multi-factor-auth": ["vendor/spryker/spryker/Bundles/MultiFactorAuthMerchantPortal/mp.public-api.ts"],
...
}
}
}
- Build the MFA frontend assets:
docker/sdk up --assets
- Integrate one of the supported MFA methods.
- Log into Merchant Portal or Agent Merchant Portal. Make sure the following applies:
- The Set up Multi-Factor Authentication menu item is displayed in the navigation
- Clicking the menu opens one of the following pages:
- Merchant Portal users:
https://mp.mysprykershop.com/multi-factor-auth/user-management-merchant-portal/set-up
- Agent Merchant Portal users:
https://mp.mysprykershop.com/multi-factor-auth/user-management-agent-merchant-portal/set-up
- Merchant Portal users:
Thank you!
For submitting the form