In This Article
zendframework/zend-expressive-authentication-oauth2
This component provides OAuth2 (server) authentication
for Expressive and
PSR-7/PSR-15
applications. It implements Zend\Expressive\Authentication\AuthenticationInterface
,
and it can be used as an adapter for zend-expressive-authentication.
This library uses the league/oauth2-server package for implementing the OAuth2 server.
If you need an introduction to OAuth2, you can read the following references:
- OAuth2 documentation from the Apigility project.
- An Introduction to OAuth 2 by DigitalOcean.
- The OAuth2 specification itself, via its official website.
Installation
In order to implement the OAuth2 server, we first need to configure it. The
first step is to generate new cryptographic keys. We need to execute the script
./vendor/bin/generate-oauth2-keys
in order to generate these keys.
$ ./vendor/bin/generate-oauth2-keys
This script will store the keys in the application's data
folder if found:
Private key stored in:
./data/oauth/private.key
Public key stored in:
./data/oauth/public.key
Encryption key stored in:
./data/oauth/encryption.key
The script will generate public and private keys, and an encryption key. These keys are used by league/oauth2-server as security settings for the OAuth2 server infrastructure.
Configuration
The OAuth2 server is configured by the authentication
configuration key in the
PSR-11 container (e.g. zend-servicemanager).
The default values are:
use League\OAuth2\Server\Grant;
return [
'private_key' => __DIR__ . '/../data/oauth/private.key',
'public_key' => __DIR__ . '/../data/oauth/public.key',
'encryption_key' => require __DIR__ . '/../data/oauth/encryption.key',
'access_token_expire' => 'P1D',
'refresh_token_expire' => 'P1M',
'auth_code_expire' => 'PT10M',
'pdo' => [
'dsn' => '',
'username' => '',
'password' => ''
],
// Set value to null to disable a grant
'grants' => [
Grant\ClientCredentialsGrant::class => Grant\ClientCredentialsGrant::class,
Grant\PasswordGrant::class => Grant\PasswordGrant::class,
Grant\AuthCodeGrant::class => Grant\AuthCodeGrant::class,
Grant\ImplicitGrant::class => Grant\ImplicitGrant::class,
Grant\RefreshTokenGrant::class => Grant\RefreshTokenGrant::class
],
];
The private_key
and public_key
values contains the paths to the previous
generated pair of keys. The encryption_key
contains the encryption key value
as a string, as stored in the data/oauth/encryption.key
file.
By default both key files are checked for correct permissions (chmod 400, 440, 600, 640 or 660 is expected, and 600 or 660 is recommended). In case the environment/operating system (e.g. Windows) does not support such a permissions, the check can be disabled:
// ...
'private_key' => [
'key_or_path' => __DIR__ . '/../data/oauth/private.key',
'key_permissions_check' => false,
],
// ...
The access_token_expire
value is the time-to-live (TTL) value of the access
token. The time period is represented using the DateInterval
format in PHP. The default value is P1D
(1 day).
The refresh_token_expire
value is the TTL used for the refresh token. The
default value is 1 month.
The auth_code_expire
value is the TTL of the authentication code, used in
the authorization code grant
scenario. The default value is 10 minutes.
The pdo
value is for the PDO database configuration. Here we need to insert
the parameters to access the OAuth2 database. These parameters are the dsn
,
the username
, and the password
, if required. The SQL structure of this
database is stored in the data/oauth2.sql
file.
If you already have a PDO service configured, you can instead pass the service
name to the pdo
key as follows:
return [
'pdo' => 'myServiceName',
];
The grants
array is for enabling/disabling grants. By default, all the supported
grants are configured to be available. If you would like to disable any of the
supplied grants, change the value for the grant to null
. Additionally,
you can extend this array to add your own custom grants.
Configure Event Listeners
- Since 1.3.0
Optional The event_listeners
and event_listener_providers
arrays may be used to enable event listeners for events published by league\oauth2-server
. See the Authorization Server Domain Events documentation. The possible event names can be found in League\OAuth2\Server\RequestEvent
.
Event Listeners
The event_listeners
key must contain an array of arrays. Each array element must contain at least 2 elements and may include a 3rd element. These roughly correspond to the arguments passed to League\Event\ListenerAcceptorInterface::addListener()
. The first element must be a string -- either the wildcard (*
) or a single event name. The second element must be either a callable, a concrete instance of League\Event\ListenerInterface
, or a string pointing to your listener service instance in the container. The third element is optional, and must be an integer if provided.
See the documentation for callable listeners.
Event Listener Providers
The event_listener_providers
key must contain an array. Each array element must contain either a concrete instance of League\Event\ListenerProviderInterface
or a string pointing to your container service instance of a listener provider.
See the documentation for listener providers.
Example config:
return [
'event_listeners' => [
// using a container service
[
\League\OAuth2\Server\RequestEvent::CLIENT_AUTHENTICATION_FAILED,
\My\Event\Listener\Service::class,
],
// using a callable
[
\League\OAuth2\Server\RequestEvent::ACCESS_TOKEN_ISSUED,
function (\League\OAuth2\Server\RequestEvent $event) {
// do something
},
],
],
'event_listener_providers' => [
\My\Event\ListenerProvider\Service::class,
],
];
OAuth2 Database
You need to provide an OAuth2 database yourself, or generate a SQLite
database with the following command (using sqlite3
for GNU/Linux):
$ sqlite3 data/oauth2.sqlite < vendor/zendframework/zend-expressive-authentication-oauth2/data/oauth2.sql
You can also create some testing values using the data/oauth2_test.sql
file:
$ sqlite3 data/oauth2.sqlite < vendor/zendframework/zend-expressive-authentication-oauth2/data/oauth2_test.sql
These commands will insert the following testing values:
- a client
client_test
with secrettest
, used for client_credentials and the password grant type. - a client
client_test2
with secrettest
, used for authorization code and implicit grant type. - a user
user_test
with passwordtest
. - a
test
scope.
For security reason, the client secret
and the user password
are stored
using the bcrypt
algorithm as used by the password_hash
function.
Configure OAuth2 Routes
As the final step, in order to use the OAuth2 server you need to configure the routes for the token endpoint and authorization.
You can read how add the token endpoint and the authorization routes in the Implement an authorization server section.
Found a mistake or want to contribute to the documentation? Edit this page on GitHub!