From 05af22c279ab275c38d386635379366d2349f796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Thu, 1 Feb 2024 19:39:23 +0100 Subject: [PATCH] Adding basic authentication by default on signed routes (#684) According to [RFC-6749](https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1) clients can choose from a number of authentication methods to authenticate with the authorization server. Section 2.3.1 states that clients can put the credentials either as a Basic authorization header or passing the credentials in the body of the POST. Right now, the default method for Socialite (in AbstractProvider) is to pass the credentials in the body of the POST. However, the spec states this: > Including the client credentials in the request-body using the two parameters is NOT RECOMMENDED and SHOULD be limited to clients unable > to directly utilize the HTTP Basic authentication scheme (or other > password-based HTTP authentication schemes). So Socialite passes the credentials using the "non recommended" way. Furthermore, this way of passing the credentials in NOT supported by all servers. However, the Basic authentication method is mandated to be compulsory per the spec: > The authorization server MUST support the HTTP Basic > authentication scheme for authenticating clients that were issued a > client password. This commit adds Basic authentication header to the requests created by the `AbstractProvider`. --- src/Two/AbstractProvider.php | 5 ++++- tests/OAuthTwoTest.php | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Two/AbstractProvider.php b/src/Two/AbstractProvider.php index e70d4c29..86e6746f 100644 --- a/src/Two/AbstractProvider.php +++ b/src/Two/AbstractProvider.php @@ -314,7 +314,10 @@ public function getAccessTokenResponse($code) */ protected function getTokenHeaders($code) { - return ['Accept' => 'application/json']; + return [ + 'Accept' => 'application/json', + 'Authorization' => 'Basic '.base64_encode($this->clientId.':'.$this->clientSecret), + ]; } /** diff --git a/tests/OAuthTwoTest.php b/tests/OAuthTwoTest.php index 2d878c10..98e7a80e 100644 --- a/tests/OAuthTwoTest.php +++ b/tests/OAuthTwoTest.php @@ -102,7 +102,7 @@ public function testTokenRequestIncludesPKCECodeVerifier() $provider = new OAuthTwoWithPKCETestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri'); $provider->http = m::mock(stdClass::class); $provider->http->expects('post')->with('http://token.url', [ - 'headers' => ['Accept' => 'application/json'], 'form_params' => ['grant_type' => 'authorization_code', 'client_id' => 'client_id', 'client_secret' => 'client_secret', 'code' => 'code', 'redirect_uri' => 'redirect_uri', 'code_verifier' => $codeVerifier], + 'headers' => ['Accept' => 'application/json', 'Authorization' => 'Basic '.base64_encode('client_id:client_secret')], 'form_params' => ['grant_type' => 'authorization_code', 'client_id' => 'client_id', 'client_secret' => 'client_secret', 'code' => 'code', 'redirect_uri' => 'redirect_uri', 'code_verifier' => $codeVerifier], ])->andReturns($response = m::mock(stdClass::class)); $response->expects('getBody')->andReturns('{ "access_token" : "access_token", "refresh_token" : "refresh_token", "expires_in" : 3600 }'); $user = $provider->user(); @@ -123,7 +123,7 @@ public function testUserReturnsAUserInstanceForTheAuthenticatedRequest() $provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri'); $provider->http = m::mock(stdClass::class); $provider->http->expects('post')->with('http://token.url', [ - 'headers' => ['Accept' => 'application/json'], 'form_params' => ['grant_type' => 'authorization_code', 'client_id' => 'client_id', 'client_secret' => 'client_secret', 'code' => 'code', 'redirect_uri' => 'redirect_uri'], + 'headers' => ['Accept' => 'application/json', 'Authorization' => 'Basic '.base64_encode('client_id:client_secret')], 'form_params' => ['grant_type' => 'authorization_code', 'client_id' => 'client_id', 'client_secret' => 'client_secret', 'code' => 'code', 'redirect_uri' => 'redirect_uri'], ])->andReturns($response = m::mock(stdClass::class)); $response->expects('getBody')->andReturns('{ "access_token" : "access_token", "refresh_token" : "refresh_token", "expires_in" : 3600 }'); $user = $provider->user();