If the Oauthsd class is not provided by a plugin or an extension, the code below must be inserted in the library at the location and under the specified name :
... /vendor/Lusitanian/oauth/src/OAuth/OAuth2/ Service/Oauthsd.php
Notes :
The scope openid indicates that we use the layer OpenID Connect.
’response_type’ => ’code’ indicates that we are using the Authorization Code Flow.
The scope "sli" allows (in particular) the single connection.
For a simple SSO use, it is useless to risk revealing the user’s data with the scope profile. By deleting the scope profile, OAuthSD will use the default scope basic, and only the sub (subject) field will be returned by the authentication request.
PHP
- <?php
- /**
- * OpenID Connect Authentication with Oauthsd
- * @link https://oa.dnc.global
- * Oauthsd.php OAuth service for the Lusitanian PHPoAuthLib
- * @link https://github.com/Lusitanian/PHPoAuthLib
- * @author Bertrand Degoy bertrand@degoy.com
- * @copyright (c) 2018 B.Degoy DnC https://degoy.com
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
- */
- //dnc4
- namespace OAuth\OAuth2\Service;
- use OAuth\OAuth2\Token\StdOAuth2Token;
- use OAuth\Common\Http\Exception\TokenResponseException;
- use OAuth\Common\Http\Uri\Uri;
- use OAuth\Common\Consumer\CredentialsInterface;
- use OAuth\Common\Http\Client\ClientInterface;
- use OAuth\Common\Storage\TokenStorageInterface;
- use OAuth\Common\Http\Uri\UriInterface;
- class Oauthsd extends AbstractService
- {
- /**
- * Available scopes (will be tested by AbstractService).
- * Might be larger than those defined by client application.
- * @link https://oa.dnc.global/-Sujets-communs-.html#definitionetgestiondesscopesdansOAuthsd
- * @see #attributes
- */
- const SCOPE_OPENID = 'openid';
- const SCOPE_PROFILE = 'profile';
- const SCOPE_EMAIL = 'email';
- const SCOPE_ADDRESS = 'address';
- const SCOPE_PHONE = 'phone';
- const SCOPE_SLI = 'sli';
- public function __construct(
- CredentialsInterface $credentials,
- ClientInterface $httpClient,
- TokenStorageInterface $storage,
- UriInterface $baseApiUri = null
- ) {
- parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
- if (null === $baseApiUri) {
- $this->baseApiUri = new Uri('https://oa.dnc.global/');
- }
- }
- /**
- * Override abstract function in order to provide required parameters in authorization request.
- * State is required by OAuthSD
- * Scopes :
- * openid is required by OpenID Connect, sli is particular to OAuthSD, basic is enough for phpBB.
- * @link https://oa.dnc.global/-Sujets-communs-.html#definitionetgestiondesscopesdansOAuthsd
- */
- {
- $additionalParameters,
- //'type' => 'web_server',
- 'client_id' => $this->credentials->getConsumerId(),
- 'redirect_uri' => $this->credentials->getCallbackUrl(),
- 'response_type' => 'code',
- 'scope' => 'openid sli', // do not mention basic.
- )
- );
- $parameters['state'] = $this->generateAuthorizationState();
- }
- $this->storeAuthorizationState($parameters['state']);
- // Build the url
- $url = clone $this->getAuthorizationEndpoint();
- foreach ($parameters as $key => $val) {
- $url->addToQuery($key, $val);
- }
- return $url;
- }
- /**
- * {@inheritdoc}
- */
- public function getAuthorizationEndpoint()
- {
- return new Uri('https://oa.dnc.global/authorize');
- }
- /**
- * {@inheritdoc}
- */
- public function getAccessTokenEndpoint()
- {
- return new Uri('https://oa.dnc.global/token');
- }
- /**
- * {@inheritdoc}
- */
- protected function getAuthorizationMethod()
- {
- return static::AUTHORIZATION_METHOD_HEADER_BEARER; // ou AUTHORIZATION_METHOD_QUERY_STRING ???
- }
- /**
- * {@inheritdoc}
- */
- protected function parseAccessTokenResponse($responseBody)
- {
- throw new TokenResponseException('Unable to parse response.');
- throw new TokenResponseException('Error in retrieving token: "' . $data['message'] . '"');
- throw new TokenResponseException('Error in retrieving token: "' . $data['name'] . '"');
- }
- $token = new StdOAuth2Token();
- $token->setAccessToken($data['access_token']);
- $token->setLifeTime($data['expires_in']);
- $token->setRefreshToken($data['refresh_token']);
- }
- $token->setExtraParams($data);
- return $token;
- }
- /**
- * {@inheritdoc}
- */
- public function requestAccessToken($code, $state = null)
- {
- if (null !== $state) {
- $this->validateAuthorizationState($state);
- }
- 'code' => $code,
- 'client_id' => $this->credentials->getConsumerId(),
- 'client_secret' => $this->credentials->getConsumerSecret(),
- 'redirect_uri' => $this->credentials->getCallbackUrl(),
- 'grant_type' => 'authorization_code',
- );
- $responseBody = $this->httpClient->retrieveResponse(
- $this->getAccessTokenEndpoint(),
- $bodyParams,
- $this->getExtraOAuthHeaders()
- );
- $token = $this->parseAccessTokenResponse($responseBody);
- $this->storage->storeAccessToken($this->service(), $token);
- return $token;
- }
- }
Roadmap
In a corporate realm, you want to have your own OIDC server and get Userinfo data in a specific format, usually using an existing user base.
For that, it would be necessary :
a setter function for the URL of the OIDC server in order to be able to choose the authentication server.
a setter function to configure the Userinfo data.
this should lead to a universal OpenID Connect client. Then try a pull request to lusitanian ?