microsoft / kiota-authentication-phpleague-php

Kiota authentication provider implementation for OAuth with PHPLeague
https://aka.ms/kiota/docs
MIT License
9 stars 5 forks source link

Add support for proxy #66

Open jasonjoh opened 9 months ago

jasonjoh commented 9 months ago

Azure Identity libraries in other languages support configuring a proxy in their credential classes. The PHP Graph SDK supports using a proxy, but these auth classes do not.

The PHP League provider supports a proxy: https://oauth2-client.thephpleague.com/usage/#using-a-proxy, so we should be able to support this.

joaofsa2000 commented 2 months ago

So i modified 2 class constructers to add a parameter for the oauthprovider with that you can insert a custom config for proxy as you will see i added the ?AbstractProvider $oauthProvider = null to both constructors


<?php 

class PhpLeagueAuthenticationProviderCustom extends BaseBearerTokenAuthenticationProvider
{
    /**
     * @var PhpLeagueAccessTokenProvider
     */
    private PhpLeagueAccessTokenProvider $accessTokenProvider;

    /**
     * @param TokenRequestContext $tokenRequestContext
     * @param array<string> $scopes
     * @param array<string> $allowedHosts
     */
    public function __construct(TokenRequestContext $tokenRequestContext, array $scopes = [], array $allowedHosts = [], ?AbstractProvider $oauthProvider = null)
    {
        $this->accessTokenProvider = new PhpLeagueAccessTokenProvider($tokenRequestContext, $scopes, $allowedHosts, oauthProvider: $oauthProvider);
        parent::__construct($this->accessTokenProvider);
    }
}

/**
 * Class GraphPhpLeagueAuthenticationProvider
 * @package Microsoft\Graph\Core\Authentication
 * @copyright 2023 Microsoft Corporation
 * @license https://opensource.org/licenses/MIT MIT License
 * @link https://developer.microsoft.com/graph
 * modified for use with custom provider settings
 */
class GraphAuthProviderCustom extends PhpLeagueAuthenticationProviderCustom
{
    /**
     * @param TokenRequestContext $tokenRequestContext
     * @param array<string> $scopes defaults to ["https://[graph national cloud host]/.default"] scope
     * @param string $nationalCloud defaults to https://graph.microsoft.com. See
     * https://learn.microsoft.com/en-us/graph/deployments
     */
    public function __construct(
        TokenRequestContext $tokenRequestContext,
        array $scopes = [],
        string $nationalCloud = NationalCloud::GLOBAL ,
        ?AbstractProvider $oauthProvider = null
    ) {
        $accessTokenProvider = new GraphPhpLeagueAccessTokenProvider($tokenRequestContext, $scopes, $nationalCloud, oauthProvider: $oauthProvider);
        parent::__construct($tokenRequestContext, $scopes, $accessTokenProvider->getAllowedHosts(), $oauthProvider);
    }

}

so now using those 2 new class constructors i just need it to use them


<?php 
use GuzzleHttp\Client as HttpClient;
use Microsoft\Kiota\Authentication\Oauth\ProviderFactory;
use League\OAuth2\Client\Provider\AbstractProvider;
use Microsoft\Graph\Core\Authentication\GraphPhpLeagueAccessTokenProvider;
use Microsoft\Kiota\Abstractions\Authentication\BaseBearerTokenAuthenticationProvider;
use Microsoft\Kiota\Authentication\PhpLeagueAccessTokenProvider;
use Microsoft\Graph\Core\NationalCloud;
use Microsoft\Kiota\Authentication\Oauth\TokenRequestContext;
use Microsoft\Graph\Core\GraphClientFactory;
use Microsoft\Graph\GraphRequestAdapter;
use Microsoft\Graph\GraphServiceClient;
......

$tokenRequestContext = new ClientCredentialContext(
            $tenantId,
            $clientID,
            $clientSecret
        );

        $nationalCloud = NationalCloud::GLOBAL;

        $tokenBaseServiceUrl = GraphPhpLeagueAccessTokenProvider::NATIONAL_CLOUD_TO_AZURE_AD_ENDPOINT[$nationalCloud] ??
            GraphPhpLeagueAccessTokenProvider::NATIONAL_CLOUD_TO_AZURE_AD_ENDPOINT[NationalCloud::GLOBAL];

        $guzzleConfig = [
            'proxy' => "",
            'verify' => false
        ];
// this httpClient is for the authentication as the sdk uses 2 seperate clients for auth and requests
        $httpClient = new HttpClient(
            $guzzleConfig
        );

        $collaborators = ["httpClient" => $httpClient];
// now i create the oauthProvider with the httpclient inside the collaborators parameter
        $oauthProvider = ProviderFactory::create(
            $tokenRequestContext,
            $collaborators,
            $tokenBaseServiceUrl,
            $nationalCloud
        );
        $scopes = ['https://graph.microsoft.com/.default'];
// using the new constructor for the GraphPhpLeagueAuthenticationProvider (GraphAuthProviderCustom) and pass the oauthProvider 
        $authProvider = new GraphAuthProviderCustom($tokenRequestContext, $scopes, oauthProvider: $oauthProvider);

// this is for the requests and i can use the same config for the new client 
        $httpClient = GraphClientFactory::createWithConfig($guzzleConfig);
        $requestAdapter = new GraphRequestAdapter($authProvider, $httpClient);
        $msgraph = GraphServiceClient::createWithRequestAdapter($requestAdapter);

i wish they would make this small change so we dont have to make it ourselves