acsystems / keycloak-authenticator-bundle
Keycloak connector for stateless JWT authentication
Package info
bitbucket.org/acwebdev/keycloak-authenticator-bundle
Type:symfony-bundle
pkg:composer/acsystems/keycloak-authenticator-bundle
Requires
- php: ^8.3
- ext-json: *
- ext-openssl: *
- firebase/php-jwt: ^7.0
- psr/log: ^1.1 || ^2.0 || ^3.0
- symfony/cache: ^6.4 || ^7.0
- symfony/http-client: ^6.4 || ^7.0
- symfony/security-bundle: ^6.4 || ^7.0
- symfony/yaml: ^6.4 || ^7.0
Requires (Dev)
README
The goal of this bundle is to provide a Keycloak token authenticator for Symfony.
Documentation
Quick start
Installation
This bundle is private and is not published on Packagist. Register the repository in your project, then require the package.
composer config repositories.acsystems-keycloak-authenticator vcs \
git@bitbucket.org:acsystemsappdev/acsystems-keycloak-authenticator-bundle.git
composer require acsystems/keycloak-authenticator-bundle:^2.0
Composer resolves the package over SSH, so whatever runs it needs read access to the repository: your own key locally, and a deploy key or repository access token in CI.
Add the bundle.
config/bundles.php
return [
ACSystems\KeycloakAuthenticatorBundle\ACSystemsKeycloakAuthenticatorBundle::class => ['all' => true]
];
Set up Symfony Security to use the custom authenticator.
config/packages/security.yaml
security:
firewalls:
main:
stateless: true
custom_authenticators:
- ACSystems\KeycloakAuthenticatorBundle\Security\KeycloakTokenAuthenticator
access_control:
# ...
Add your keycloak base url and realm
config/packages/keycloak_authenticator.yaml:
acsystems_keycloak_authenticator:
keycloak_authenticator:
base_uri: 'https://example.com/'
realm: 'example-realm'
Configurable parameters
| Name | Type | Usage |
|---|---|---|
| base_uri | string, required | URL to your keycloak instance. A trailing / is added if you leave it off. |
| realm | optional string | Realm name. Derived from the token when absent - see the security note below. |
| client_id | optional string | Human readable client_id, derived from the token's azp when absent |
| jwks_cache_ttl | optional int, default 3600 | Seconds to cache a realm's JWKS document. Only successful responses are cached. |
Pin your realm
When realm is omitted it is derived from the iss claim of the incoming token, which has
not been verified at that point. The bundle only ever fetches keys from your configured
base_uri, so this cannot be pointed at a foreign server, but it does mean a token issued
by any realm on your Keycloak instance will authenticate. If your application serves a
single realm, set realm explicitly.
Likewise, leaving client_id at its default derives the client from the token's azp claim,
so roles are read out of whichever client the token names. Set client_id when the
application only trusts roles from one client.
Error handling
| Situation | Result |
|---|---|
No Authorization header | 401 from the bundle's entry point |
| Expired, malformed, or badly signed token | 401 via CustomUserMessageAuthenticationException |
| Keycloak unreachable or serving an unusable JWKS | 503, logged at error level as JwksUnavailableException |
Responses only carry the caller-safe message; the underlying reason is logged rather than returned, so JWKS URLs and decoder internals are not exposed to unauthenticated callers.
Upgrading
For version migrations instructions see upgrade instructions.
Supported platforms
These are the platforms which are officially supported by this package. Any other versions might work but is not guaranteed.
| Platform | Version |
|---|---|
| PHP | ^8.3 |
| Symfony | ^6.4 || ^7.0 |
Contributing
Please read our contribution guidelines before contributing.