b2pweb / parroauth2-client
B2P OAuth 2 client implementation
Installs: 9 788
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
pkg:composer/b2pweb/parroauth2-client
Requires
- php: ~8.1.0 | ~8.2.0 | ~8.3.0 | ~8.4.0
- ext-json: *
- b2pweb/jwt: ~1.0
- php-http/client-common: ~2.4
- php-http/discovery: ~1.14
- psr/clock: ~1.0
- psr/http-client: ~1.0
- psr/http-factory: ~1.0
- psr/http-factory-implementation: ~1.0
- psr/http-message: ~1.0
- psr/http-message-implementation: ~1.0
- psr/simple-cache: ~1.0|~2.0|~3.0
Requires (Dev)
- bshaffer/oauth2-server-php: ~1.11
- cache/array-adapter: ~1.1
- nyholm/psr7: ~1.4
- php-http/curl-client: ~2.2
- php-http/mock-client: ~1.3
- phpunit/phpunit: ~10.5
- squizlabs/php_codesniffer: ~3.6
- vimeo/psalm: ~6.0@stable
README
OAuth 2.0 and OpenID Connect client library for PHP.
Installation
Install with composer :
composer require b2pweb/parroauth2-client
Simple usage
For a simple usage, using Authorization Server Metadata RFC 8414 or OpenID Connection discovery, you can see example directory.
Password authentication
Authenticate to a provider using password grant type (cf: RFC 6749#4.3).
This example simply configure the OAuth 2.0 client, and call the token endpoint of the provider with owner's credentials (i.e. username and password).
Standard authentication flow
Implements the client-side authentication using authorization_code grant type (cf: RFC 6749#4.1) which is the recommended authorization flow.
- First the session storage is configured
- Then the provider and the client are loaded
- Register extensions
- JwtAccessTokento enable local introspection of the access token
- Pkceto enable PKCE RFC 7636 to mitigate authorization code interception attack
- IdTokenValidator(only for OpenID) to enable verification of the ID Token
- TokenStoragestore the access token into session, and provide it into oauth endpoints
- RequiredScopeValidatorassert given scopes are provided in the access token.
 
- Perform the authentication process if the token is not present or expired, by using AuthorizationCodeFlow
- Once authenticated, perform userinfo and introspection
- Also implements the logout action, using revocation endpoint and redirect to the OP for stop the session
Access token check on server side
Check the access token passed as Authorization: Bearer header using local introspection.
Advanced usage
Configure provider manually
If the authentication provider do not implement the auto-discovery, or you want to configure manually,
you can use the ProviderBuilder :
$loader = new \Parroauth2\Client\Provider\ProviderLoader(); // Configure and create the provider $provider = $loader->builder('http://my-op.example.com') ->openid() // Enable openid connection on the endpoint // Configure endpoints ->tokenEndPoint('/token') ->authorizationEndPoint('/auth') ->introspectionEndPoint('/introspect') // Configure public key for local introspection ->addKeyFile('./keys/provider.pub') ->create() ; // Create the client $client = $provider->client((new \Parroauth2\Client\ClientConfig('client_id'))->setSecret('secret'));
Lazy provider
In some case, you should delay the loading of the provider, and only load it when it's necessary. This is necessary when use a dependency injection container which inject the client or the provider into a service.
In this context you can use ProviderLoader::lazy(), which allows loading provider
only when calling OP endpoints.
Design consideration
EndPoints
End points are immutable, any call to setters will return a new instance of the endpoint.
So the following code is invalid :
/** @var $client \Parroauth2\Client\ClientInterface */ $token = $client->endPoints()->token(); $token->refresh('MyRefreshToken'); // This instruction has no effect : the return value is ignored $token->call(); // This call will fail : no token has been provided
To save a state, like provide a token, you should use Extensions with an EndPointTransformerInterface,
or inject parameters manually at each endpoint calls.
Extensions
Extension consist of a class with single method configure() which takes the client as parameter.
They permit modifying or configuring any mutable elements of client like :
- Change client configuration
- Register or replace an end point
- Register an EndPointTransformerInterface
To simply apply an endpoint transformer, you can inherit AbstractEndPointTransformerExtension,
implement the desired endpoint transformation method, and use CallableEndPointInterface::onResponse()
to intercept responses.
Note: because endpoints are immutable, the endpoint transformer must return the configured instance of the endpoint