Identity Manager
IdentityManager is the contract between the authentication middleware and your application's user store. By default the framework uses a SQL-backed implementation, but you can replace it with your own.
Default SQL implementation
The package ships with DefaultIdentityManager, which uses PDO-backed repositories generated by mvc auth:enable. Register it with:
use PhpMvc\Security\Dependencies;
Dependencies::configure($container);
This binds:
IdentityManager→DefaultIdentityManagerUserIdentityRepository→SqlUserIdentityRepositorySignInSessionRepository→SqlSignInSessionRepository- Challenge repositories for sign-up and password reset
The database schema is created by the migration generated via mvc auth:enable.
Custom IdentityManager
To use an external user store (LDAP, OAuth, a different database schema):
-
Enable authentication without migrations:
vendor/bin/mvc auth:enable --skip-migrations -
Implement
IdentityManager:use PhpMvc\Security\IdentityManager; use PhpMvc\Security\Identity; final class LdapIdentityManager implements IdentityManager { public function __construct( private readonly LdapClient $ldap, ) {} public function getIdentity(?string $token): Identity { $user = $token !== null ? $this->ldap->findByToken($token) : null; return new MyIdentity($user); } } -
Register your implementation in the container (instead of calling
Dependencies::configure()):$container->set(IdentityManager::class, LdapIdentityManager::class);
ChallengeNotificator
Dependencies::configure() does not register ChallengeNotificator. The sign-up and password-reset use cases depend on this interface to deliver one-time tokens to the user (by email, SMS, a queue, etc.). You must register a concrete implementation in your composition root:
$container->set(ChallengeNotificator::class, EmailChallengeNotificator::class);
Example: background-task notificator
A common pattern is to enqueue a background task instead of sending email synchronously:
use PhpMvc\Security\Domain\Services\ChallengeNotificator;
use PhpMvc\Security\Domain\Entities\SignUpChallenge;
use PhpMvc\Security\Domain\Entities\ResetPasswordChallenge;
use PhpMvc\BackgroundTasks\Application\RegisterTask\RegisterTask;
final class BackgroundTaskChallengeNotificator implements ChallengeNotificator
{
public function __construct(
private readonly RegisterTask $registerTask,
) {}
public function sendSignUpChallenge(string $email, SignUpChallenge $challenge): void
{
$this->registerTask->execute(
type: 'send_sign_up_challenge_email',
payload: ['email' => $email, 'token' => $challenge->token],
);
}
public function sendResetPasswordChallenge(string $email, ResetPasswordChallenge $challenge): void
{
$this->registerTask->execute(
type: 'send_reset_password_challenge_email',
payload: ['email' => $email, 'token' => $challenge->token],
);
}
}
Identity interface
Your identity object must implement the Identity contract:
interface Identity
{
public function isAuthenticated(): bool;
public function username(): string;
public function getRoles(): array;
public function hasRole(string $role): bool;
}
getRoles() is used by the Authorization middleware to enforce route-level role restrictions.