b2pweb / parroauth2-client
B2P OAuth 2 client implementation
Installs: 7 466
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Requires
- php: ~7.1 | ~8.0.0 | ~8.1.0 | ~8.2.0 | ~8.3.0
- ext-json: *
- b2pweb/jwt: ~1.0
- php-http/client-common: ~2.4
- php-http/discovery: ~1.14
- 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
- spomky-labs/base64url: ~2.0
- web-token/jwt-checker: ~1.3|~2.0|~3.0
- web-token/jwt-key-mgmt: ~1.3|~2.0|~3.0
- web-token/jwt-signature: ~1.3|~2.0|~3.0
- web-token/jwt-signature-algorithm-ecdsa: ~1.3|~2.0|~3.0
- web-token/jwt-signature-algorithm-eddsa: ~1.3|~2.0|~3.0
- web-token/jwt-signature-algorithm-hmac: ~1.3|~2.0|~3.0
- web-token/jwt-signature-algorithm-none: ~1.3|~2.0|~3.0
- web-token/jwt-signature-algorithm-rsa: ~1.3|~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: ~7.0 | ~8.5
- squizlabs/php_codesniffer: ~3.6
- vimeo/psalm: ~4.9
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
JwtAccessToken
to enable local introspection of the access tokenPkce
to enable PKCE RFC 7636 to mitigate authorization code interception attackIdTokenValidator
(only for OpenID) to enable verification of the ID TokenTokenStorage
store the access token into session, and provide it into oauth endpointsRequiredScopeValidator
assert 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