Configuration

The package is configured with environment variables, that the services of the package read (%env(...)%), and with the services and the routes that the application imports. Everything has a default, and the ones that are not safe to guess (the client of Keycloak, the database) have none.

What the application imports

The services and the routes are the same for every provider: the application imports them and chooses the provider with AUTH_PROVIDER.

# 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' }

The services bring everything that the application needs: the manager of the authentication with its two channels (web and API), the authorization with the access rules, the translations of the package, and the three providers, of which only the chosen one is made. See How it works. The session and the flash messages are not part of the provider: the middlewares and the variables SESSION_* come from derafu/session, which a site that uses derafu/foundation already has. The routes are /auth/login, /auth/logout and /auth/profile (see Profile), /auth/callback and the routes of the API tokens: the callback answers 404 with a provider whose login is a form, and the tokens with one that has none. The logout accepts only POST (see Security).

The middlewares

The application puts four middlewares between the router and the dispatcher, in this order (the others of the list are the ones that every site has):

Psr\Http\Server\RequestHandlerInterface:
    class: Derafu\Http\Service\RequestHandler
    public: true
    arguments:
        $middlewares:
            - '@Derafu\Http\Middleware\StaticFilesMiddleware'
            - '@Derafu\Http\Middleware\RequestFactoryMiddleware'
            - '@Derafu\Http\Middleware\RouterMiddleware'
            - '@Mezzio\Session\SessionMiddleware'
            - '@Mezzio\Flash\FlashMessageMiddleware'
            - '@Derafu\Auth\Authentication\AuthenticationMiddleware'
            - '@Derafu\Auth\Authorization\AuthorizationMiddleware'
            - '@Derafu\Http\Middleware\DispatcherMiddleware'
            - '@Derafu\Http\Middleware\ResponseNormalizerMiddleware'

With the database provider the middleware of the CSRF tokens of derafu/csrf goes after the flash messages (see Database).

The router goes first because the login and the logout have routes: a path that has no route never reaches the authentication. The session and the flash messages go before the authentication, which uses them, and the authentication before the authorization, which reads the user that it puts in the request.

The cache pool

The providers use a PSR-6 pool (Psr\Cache\CacheItemPoolInterface): the database and htpasswd providers for the count of the failed logins (they need it: without one the first count fails with a message that says so), and the Keycloak provider for the keys of the realm (it is optional, without it the keys are read in every request that verifies a token). derafu/foundation registers one in the cache directory of the kernel. An application that has its own declares the same id.

The provider

Variable Type Default Description
AUTH_PROVIDER string Required. The provider of the application: keycloak, database or htpasswd, or the name of one that the application adds (see How it works). Set only the variables of that provider (AUTH_KEYCLOAK_*, AUTH_DATABASE_* or AUTH_HTPASSWD_*).

The variable is read when a piece of the provider is needed (the login, the API, the profile), not when the container is built: with it empty or wrong the pages that do not use the provider keep working, and what needs it fails with a message that says what to set and which providers there are.

Variables of the access rules

They are the same in every provider, and they are about who may enter which path, not about how a request is identified.

Variable Type Default Description
AUTH_ENABLED bool true Whether the protected paths are protected. With false no path asks for a user, but the login and the logout still work, and a user that logged in is still the user of the request. For development and for tests.
AUTH_PROTECTED_PATHS json [] The protected paths: a list, or a map from the path to its roles. See Route Protection.

Variables of the web channel

Variable Type Default Description
AUTH_WEB_LOGOUT_PATH string /auth/logout The logout path. It must match the logout route.
AUTH_WEB_LOGIN_REDIRECT_PATH string / Where the user goes after the login when no page was requested before.
AUTH_WEB_LOGOUT_REDIRECT_PATH string Keycloak: /, database and htpasswd: /auth/login Where the user goes after the logout.
AUTH_WEB_UNAUTHORIZED_REDIRECT_PATH string Keycloak: /, database and htpasswd: /auth/login Where a user that is not logged in goes when there is no provider to send it to (the database and htpasswd providers send it to their login page).
AUTH_WEB_REFRESH_INTERVAL_SECONDS int Keycloak: the expiration of the access token, database and htpasswd: 300 Seconds between two times that the session asks the provider again about its user (its roles, whether it still exists). 0 or empty is the default. See The user of the session is a copy.

The login path is not a variable: it is the callback (AUTH_KEYCLOAK_WEB_CALLBACK_PATH) in Keycloak and /auth/login in the database and htpasswd providers.

Variables of the API channel

Variable Type Default Description
AUTH_API_PATHS json ["/api"] The paths where a client is authenticated with the header Authorization (no session, 401 in JSON). A list of paths. See API.
AUTH_API_REALM string API The label of the protection space, in the header WWW-Authenticate of the 401 of the API. Not the realm of Keycloak. See API.

Variables of the session

The session is the one of Mezzio, with the session of PHP, and its variables (SESSION_NAME, SESSION_COOKIE_SECURE, SESSION_COOKIE_SAMESITE and the others) are the ones of derafu/session.

Variables of Keycloak

Variable Type Required Default Description
AUTH_KEYCLOAK_URL string Yes - URL of the Keycloak server.
AUTH_KEYCLOAK_CLIENT_ID string Yes - ID of the client.
AUTH_KEYCLOAK_CLIENT_SECRET string Yes - Secret of the client.
AUTH_KEYCLOAK_WEB_REDIRECT_URI string Yes - The callback of the application, as Keycloak must send the user back (a valid redirect URI of the client).
AUTH_KEYCLOAK_REALM string No master The realm.
AUTH_KEYCLOAK_WEB_SCOPES json No ["openid", "profile", "email"] Scopes. openid is needed: it gives the ID token.
AUTH_KEYCLOAK_WEB_CALLBACK_PATH string No /auth/callback Path of the callback: it is the login path of the provider.
AUTH_KEYCLOAK_ISSUER string No the URL of the realm The iss that the tokens must have. Set it if the application reaches Keycloak by another URL than the one Keycloak publishes (inside a network of containers, for example).
AUTH_KEYCLOAK_WEB_END_SESSION bool No true Whether the logout also ends the session of the user in Keycloak.
AUTH_KEYCLOAK_WEB_POST_LOGOUT_REDIRECT_URI string No the page that follows the logout, in the site of the redirect URI Where Keycloak sends the user after the logout. It must be a valid post logout redirect URI of the client.
AUTH_KEYCLOAK_API_AUDIENCE string No the client id The audience (aud) that an access token must have to call the API. See API.
AUTH_KEYCLOAK_API_CLIENT_ID string No the client of the application The client of the API, if it has one of its own: the one that asks Keycloak about the tokens. It goes with its secret. See API.
AUTH_KEYCLOAK_API_CLIENT_SECRET string No the secret of the client of the application The secret of the client of the API.
AUTH_KEYCLOAK_API_INTROSPECTION bool No true Whether Keycloak is asked, in every request of the API, if the token is still active. With true the audience must be the client that asks. See API.
AUTH_KEYCLOAK_HTTP_TIMEOUT_SECONDS int No 30 Seconds of timeout of the requests to Keycloak.
AUTH_KEYCLOAK_HTTP_CONNECT_TIMEOUT_SECONDS int No 30 Seconds of timeout of the connection.
AUTH_KEYCLOAK_HTTP_VERIFY bool No true Verification of the certificate of Keycloak. Set it to false only in development, with a certificate that is not valid.
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

How the login works, and how to configure the client in Keycloak, is in Keycloak.

Variables of the database provider

Variable Type Default Description
AUTH_DATABASE_URL string DATABASE_URL The DSN of PDO. If it is empty, DATABASE_URL is used (the connection that the application already has). %kernel.project_dir% is replaced by the directory of the project (useful with SQLite).
AUTH_DATABASE_USER_TABLE string user Table of the users.
AUTH_DATABASE_USER_FIELD_IDENTITY string email Column of the identity.
AUTH_DATABASE_USER_FIELD_PASSWORD string password Column of the hash of the password.
AUTH_DATABASE_USER_FIELD_ACTIVE string active Column that says whether the user is active. It is used by the default query of AUTH_DATABASE_USER_SQL_IS_ACTIVE.
AUTH_DATABASE_USER_SQL_GET_ROLES string the roles of <table>_role and role Query of the roles, with the parameter :identity: the first column of each row is a role.
AUTH_DATABASE_USER_SQL_GET_DETAILS string SELECT * FROM <table> WHERE <identity> = :identity Query of the details of the user, with the parameter :identity: the first row.
AUTH_DATABASE_USER_SQL_IS_ACTIVE string SELECT <active> FROM <table> WHERE <identity> = :identity Query that says whether the user is active, with the parameter :identity: the first value of the first row. false turns the check off. See Database.
AUTH_DATABASE_LOGIN_MAX_ATTEMPTS int 5 Failed attempts of an identity from a network before the login is limited.
AUTH_DATABASE_LOGIN_LOCK_SECONDS int 900 Seconds of the window of the failed attempts, and so of the limit.

More in Database.

Variables of the htpasswd provider

Variable Type Default Description
AUTH_HTPASSWD_PATH string - (required) Path of the .htpasswd file. %kernel.project_dir% is replaced by the directory of the project.
AUTH_HTPASSWD_GROUP_PATH string empty Path of the .htgroup file with the roles of the users (role: user1 user2). Empty: no roles. See Htpasswd.
AUTH_HTPASSWD_LOGIN_MAX_ATTEMPTS int 5 Failed attempts of an identity from a network before the login is limited.
AUTH_HTPASSWD_LOGIN_LOCK_SECONDS int 900 Seconds of the window of the failed attempts, and so of the limit.

More in Htpasswd.

Changing the services

The services of the package are declared by their interface or class, so an application replaces one by declaring the same id after the import. For example, the anonymous user, that every piece that needs one takes if the application declares it (without it they make AnonymousUser):

Derafu\Auth\Contract\UserInterface:
    class: App\Auth\GuestUser

Or the flow that a provider gives to the web channel:

Derafu\Auth\Contract\WebFlowInterface:
    class: App\Auth\MyKeycloakWebFlow
    lazy: true

The services are lazy (lazy: true), and the ones that an application declares should be too. The translator reaches the channels by autowiring when the application has one (Symfony\Contracts\Translation\TranslatorInterface): see Translations.

The configuration without a container

The configuration classes take an array, with the same keys that the YAML gives them, so the pieces work without a container too (this is how the tests of the package use them). The manager of the authentication is assembled with the channels, the one of each provider included:

use Derafu\Auth\Authentication\AuthenticationManager;
use Derafu\Auth\Authentication\Channel\Api\ApiChannel;
use Derafu\Auth\Authentication\Channel\Api\ApiConfiguration;
use Derafu\Auth\Authentication\Channel\Web\WebChannel;
use Derafu\Auth\Authentication\Channel\Web\WebConfiguration;
use Derafu\Auth\Authorization\AccessRules;
use Derafu\Auth\Provider\Keycloak\Api\KeycloakBearerScheme;
use Derafu\Auth\Provider\Keycloak\KeycloakConfiguration;
use Derafu\Auth\Provider\Keycloak\KeycloakUserRepository;
use Derafu\Auth\Provider\Keycloak\Web\KeycloakSessionManager;
use Derafu\Auth\Provider\Keycloak\Web\KeycloakWebFlow;

$keycloak = new KeycloakConfiguration([
    'keycloak_url' => 'https://auth.example.com',
    'realm' => 'my-realm',
    'client_id' => 'my-app',
    'client_secret' => 'the-secret',
    'redirect_uri' => 'https://app.example.com/auth/callback',
]);
$users = new KeycloakUserRepository($keycloak);
$sessions = new KeycloakSessionManager();
$web = new WebConfiguration(['logout_redirect_path' => '/bye']);
$rules = new AccessRules(['protected_paths' => ['/dashboard']]);

$authentication = new AuthenticationManager(
    [
        // Asked first.
        new ApiChannel(new ApiConfiguration(['paths' => ['/api']]), new KeycloakBearerScheme($users, $keycloak)),
        // The last one: the channel of every request that is not of another.
        new WebChannel(new KeycloakWebFlow($users, $keycloak, $web, $sessions), $web, $sessions),
    ],
    $rules
);
On this page

Last updated on 10/10/2026 by Anonymous