Derafu: Auth
Authentication and authorization for PHP applications, built on the PSR-15 middleware of Mezzio: mezzio-authentication, mezzio-authorization, mezzio-session and mezzio-flash. It keeps authentication (who is asking) apart from authorization (may they enter), and it has two channels (the web, with a session, and the API, with the credentials in the header) and three providers, of which the application uses one (see How it works):
| Provider | Who knows the users | Page |
|---|---|---|
| Keycloak | A Keycloak server: OpenID Connect, authorization code flow with PKCE. | Keycloak |
| Database | A table of a database, with the hash of the password. | Database |
| Htpasswd | An .htpasswd file, with bcrypt hashes: only a username and a password. |
Htpasswd |
What it gives
- Authentication middleware with the user in the request, and the unauthorized response when there is none: a redirect (to Keycloak, or to the login), or a JSON
401withWWW-Authenticatefor the API paths, where the client sends its credentials in the header (see API). - Login and logout as the way in and the way out: they are handled before looking at what is protected, the session id is renewed (against session fixation) and the logout is a POST of the same origin (against CSRF).
- Keycloak done by the standard:
state,nonceand PKCE, the tokens verified with the keys of the realm (cached), the refresh of the tokens, and the logout that ends the session in Keycloak too. - Database provider: the login form (protected with a CSRF token and a captcha), the limit of failed attempts, the hash made again when its algorithm is old, and a user that does not exist takes as long as one that does.
- Protected paths by prefix, with the roles that each one needs. A route can declare its own roles, which also protect its path, and the roles of the site win over the ones of a route that it imports.
- Account pages for every provider: a login route, a profile page (data, API and session), with templates that a site can override (see Profile). With Keycloak, the user makes API tokens there.
- Translatable: the messages, the flash messages and the login form have their translation (Spanish ships with the package).
Quick start (Keycloak)
The libraries of the provider are not required by the package, because the database provider does not need them:
composer require derafu/auth league/oauth2-client firebase/php-jwt
Import the services and the routes:
# config/services.yaml
imports:
- { resource: '../vendor/derafu/auth/resources/config/auth-services.yaml' }
# config/routes.yaml
imports:
- { resource: '../vendor/derafu/auth/resources/config/auth-routes.yaml' }
For Derafu HTTP or Foundation, import auth-http-services.yaml instead: it adds the authentication and authorization middlewares to the shared pipeline in order, without copying the request handler configuration. For another PSR-15 pipeline, attach the middlewares as described in Configuration. Configure the environment (see Configuration for every variable):
AUTH_PROVIDER=keycloak
AUTH_KEYCLOAK_URL=https://auth.example.com
AUTH_KEYCLOAK_REALM=my-realm
AUTH_KEYCLOAK_CLIENT_ID=my-app
AUTH_KEYCLOAK_CLIENT_SECRET=the-secret
AUTH_KEYCLOAK_WEB_REDIRECT_URI=https://app.example.com/auth/callback
AUTH_PROTECTED_PATHS='["/dashboard", "/admin"]'
And configure the client in Keycloak as Keycloak says (redirect URI, post logout redirect URI and PKCE).
Access the user
The authentication middleware puts the user in the request, with the name of the interface of Mezzio:
use Mezzio\Authentication\UserInterface;
$user = $request->getAttribute(UserInterface::class);
if ($user !== null && !$user->isAnonymous()) {
$identity = $user->getIdentity();
$roles = $user->getRoles();
$email = $user->getDetail('email');
}
On a path that is not protected the user is the anonymous one (isAnonymous() is true, and its role is anonymous). More in Examples.
Where to go next
- How it works: the channels, the providers and the rules of access, and how to add a channel.
- Configuration: every environment variable and the services.
- Keycloak, Database and Htpasswd: the providers.
- Profile: the account pages and the API tokens.
- Route Protection, API (credentials in the header) and Authorization.
- Security: what the package protects against, and what is left to the application.
- Translations and Testing.