Giter Site home page Giter Site logo

thenetworg / oauth2-azure Goto Github PK

View Code? Open in Web Editor NEW
223.0 13.0 107.0 243 KB

Azure AD provider for the OAuth 2.0 Client.

Home Page: https://packagist.org/packages/thenetworg/oauth2-azure

License: MIT License

PHP 98.34% Dockerfile 1.66%
azure php azure-active-directory microsoft microsoft-graph aad aad-b2c

oauth2-azure's Introduction

Azure Active Directory Provider for OAuth 2.0 Client

Latest Version Total Downloads Software License

This package provides Azure Active Directory OAuth 2.0 support for the PHP League's OAuth 2.0 Client.

Table of Contents

Installation

To install, use composer:

composer require thenetworg/oauth2-azure

Usage

Usage is the same as The League's OAuth client, using \TheNetworg\OAuth2\Client\Provider\Azure as the provider.

Authorization Code Flow

$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
    'clientId'          => '{azure-client-id}',
    'clientSecret'      => '{azure-client-secret}',
    'redirectUri'       => 'https://example.com/callback-url',
    //Optional using key pair instead of secret
    'clientCertificatePrivateKey' => '{azure-client-certificate-private-key}',
    //Optional using key pair instead of secret
    'clientCertificateThumbprint' => '{azure-client-certificate-thumbprint}',
    //Optional
    'scopes'            => ['openid'],
    //Optional
    'defaultEndPointVersion' => '2.0'
]);

// Set to use v2 API, skip the line or set the value to Azure::ENDPOINT_VERSION_1_0 if willing to use v1 API
$provider->defaultEndPointVersion = TheNetworg\OAuth2\Client\Provider\Azure::ENDPOINT_VERSION_2_0;

$baseGraphUri = $provider->getRootMicrosoftGraphUri(null);
$provider->scope = 'openid profile email offline_access ' . $baseGraphUri . '/User.Read';

if (isset($_GET['code']) && isset($_SESSION['OAuth2.state']) && isset($_GET['state'])) {
    if ($_GET['state'] == $_SESSION['OAuth2.state']) {
        unset($_SESSION['OAuth2.state']);

        // Try to get an access token (using the authorization code grant)
        /** @var AccessToken $token */
        $token = $provider->getAccessToken('authorization_code', [
            'scope' => $provider->scope,
            'code' => $_GET['code'],
        ]);

        // Verify token
        // Save it to local server session data
        
        return $token->getToken();
    } else {
        echo 'Invalid state';

        return null;
    }
} else {
    // // Check local server's session data for a token
    // // and verify if still valid 
    // /** @var ?AccessToken $token */
    // $token = // token cached in session data, null if not found;
    //
    // if (isset($token)) {
    //    $me = $provider->get($provider->getRootMicrosoftGraphUri($token) . '/v1.0/me', $token);
    //    $userEmail = $me['mail'];
    //
    //    if ($token->hasExpired()) {
    //        if (!is_null($token->getRefreshToken())) {
    //            $token = $provider->getAccessToken('refresh_token', [
    //                'scope' => $provider->scope,
    //                'refresh_token' => $token->getRefreshToken()
    //            ]);
    //        } else {
    //            $token = null;
    //        }
    //    }
    //}
    //
    // If the token is not found in 
    // if (!isset($token)) {
        $authorizationUrl = $provider->getAuthorizationUrl(['scope' => $provider->scope]);

        $_SESSION['OAuth2.state'] = $provider->getState();

        header('Location: ' . $authorizationUrl);

        exit;
    // }

    return $token->getToken();
}

Advanced flow

The Authorization Code Grant Flow is a little bit different for Azure Active Directory. Instead of scopes, you specify the resource which you would like to access - there is a param $provider->authWithResource which will automatically populate the resource param of request with the value of either $provider->resource or $provider->urlAPI. This feature is mostly intended for v2.0 endpoint of Azure AD (see more here).

Using custom parameters

With oauth2-client of version 1.3.0 and higher, it is now possible to specify custom parameters for the authorization URL, so you can now make use of options like prompt, login_hint and similar. See the following example of obtaining an authorization URL which will force the user to reauthenticate:

$authUrl = $provider->getAuthorizationUrl([
    'prompt' => 'login'
]);

You can find additional parameters here.

Using a certificate key pair instead of the shared secret

  • Generate a key pair, e.g. with:
openssl genrsa -out private.key 2048
openssl req -new -x509 -key private.key -out publickey.cer -days 365
  • Upload the publickey.cer to your app in the Azure portal
  • Note the displayed thumbprint for the certificate (it looks like B4A94A83092455AC4D3AC827F02B61646EAAC43D)
  • Put that thumbprint into the clientCertificateThumbprint constructor option
  • Put the contents of private.key into the clientCertificatePrivateKey constructor option
  • You can omit the clientSecret constructor option

Logging out

If you need to quickly generate a logout URL for the user, you can do following:

// Assuming you have provider properly initialized.
$post_logout_redirect_uri = 'https://www.msn.com'; // The logout destination after the user is logged out from their account.
$logoutUrl = $provider->getLogoutUrl($post_logout_redirect_uri);
header('Location: '.$logoutUrl); // Redirect the user to the generated URL

Call on behalf of a token provided by another app

// Use token provided by the other app
// Make sure the other app mentioned this app in the scope when requesting the token
$suppliedToken = '';  

$provider = xxxxx;// Initialize provider

// Call this to get claims
// $claims = $provider->validateAccessToken($suppliedToken);

/** @var AccessToken $token */
$token = $provider->getAccessToken('jwt_bearer', [
    'scope' => $provider->scope,
    'assertion' => $suppliedToken,
    'requested_token_use' => 'on_behalf_of',
]);

Making API Requests

This library also provides easy interface to make it easier to interact with Azure Graph API and Microsoft Graph, the following methods are available on provider object (it also handles automatic token refresh flow should it be needed during making the request):

  • get($ref, $accessToken, $headers = [])
  • post($ref, $body, $accessToken, $headers = [])
  • put($ref, $body, $accessToken, $headers = [])
  • delete($ref, $body, $accessToken, $headers = [])
  • patch($ref, $body, $accessToken, $headers = [])
  • getObjects($tenant, $ref, $accessToken, $headers = []) This is used for example for listing large amount of data - where you need to list all users for example - it automatically follows odata.nextLink until the end.
    • $tenant tenant has to be provided since the odata.nextLink doesn't contain it.
  • request($method, $ref, $accessToken, $options = []) See #36 for use case.

Please note that if you need to create a custom request, the method getAuthenticatedRequest and getResponse can still be used.

Variables

  • $ref The URL reference without the leading /, for example myOrganization/groups
  • $body The contents of the request, make has to be either string (so make sure to use json_encode to encode the request)s or stream (see Guzzle HTTP)
  • $accessToken The access token object obtained by using getAccessToken method
  • $headers Ability to set custom headers for the request (see Guzzle HTTP)

Resource Owner

With version 1.1.0 and onward, the Resource Owner information is parsed from the JWT passed in access_token by Azure Active Directory. It exposes few attributes and one function.

Example:

$resourceOwner = $provider->getResourceOwner($token);
echo 'Hello, '.$resourceOwner->getFirstName().'!';

The exposed attributes and function are:

  • getId() - Gets user's object id - unique for each user
  • getFirstName() - Gets user's first name
  • getLastName() - Gets user's family name/surname
  • getTenantId() - Gets id of tenant which the user is member of
  • getUpn() - Gets user's User Principal Name, which can be also used as user's e-mail address
  • claim($name) - Gets any other claim (specified as $name) from the JWT, full list can be found here

Microsoft Graph

Calling Microsoft Graph is very simple with this library. After provider initialization simply change the API URL followingly (replace v1.0 with your desired version):

// Mention Microsoft Graph scope when initializing the provider 
$baseGraphUri = $provider->getRootMicrosoftGraphUri(null);
$provider->scope = 'your scope ' . $baseGraphUri . '/User.Read';

// Call a query
$provider->get($provider->getRootMicrosoftGraphUri($token) . '/v1.0/me', $token);

After that, when requesting access token, refresh token or so, provide the resource with value https://graph.microsoft.com/ in order to be able to make calls to the Graph (see more about resource here).

Protecting your API - experimental

With version 1.2.0 you can now use this library to protect your API with Azure Active Directory authentication very easily. The Provider now also exposes validateAccessToken(string $token) which lets you pass an access token inside which you for example received in the Authorization header of the request on your API. You can use the function followingly (in vanilla PHP):

// Assuming you have already initialized the $provider

// Obtain the accessToken - in this case, we are getting it from Authorization header.
// If you're instead using a persisted access token you got from $provider->getAccessToken,
// you'll have to feed its id token to validateAccessToken like so: $provider->validateAccessToken($accessTokenn->getIdToken());
$headers = getallheaders();
// Assuming you got the value of Authorization header as "Bearer [the_access_token]" we parse it
$authorization = explode(' ', $headers['Authorization']);
$accessToken = $authorization[1];

try {
    $claims = $provider->validateAccessToken($accessToken);
} catch (Exception $e) {
    // Something happened, handle the error
}

// The access token is valid, you can now proceed with your code. You can also access the $claims as defined in JWT - for example roles, group memberships etc.

You may also need to access some other resource from the API like the Microsoft Graph to get some additional information. In order to do that, there is urn:ietf:params:oauth:grant-type:jwt-bearer grant available (RFC). An example (assuming you have the code above working and you have the required permissions configured correctly in the Azure AD application):

$graphAccessToken = $provider->getAccessToken('jwt_bearer', [
    'resource' => 'https://graph.microsoft.com/v1.0/',
    'assertion' => $accessToken,
    'requested_token_use' => 'on_behalf_of'
]);

$me = $provider->get('https://graph.microsoft.com/v1.0/me', $graphAccessToken);
print_r($me);

Just to make it easier so you don't have to remember entire name for grant_type (urn:ietf:params:oauth:grant-type:jwt-bearer), you just use short jwt_bearer instead.

Azure Active Directory B2C - experimental

You can also now very simply make use of Azure Active Directory B2C. Before authentication, change the endpoints using pathAuthorize, pathToken and scope and additionally specify your login policy. Please note that the B2C support is still experimental and wasn't fully tested.

$provider->pathAuthorize = "/oauth2/v2.0/authorize";
$provider->pathToken = "/oauth2/v2.0/token";
$provider->scope = ["idtoken"];

// Specify custom policy in our authorization URL
$authUrl = $provider->getAuthorizationUrl([
    'p' => 'b2c_1_siup'
]);

Multipurpose refresh tokens - experimental

In cause that you need to access multiple resources (like your API and Microsoft Graph), you can use multipurpose refresh tokens. Once obtaining a token for first resource, you can simply request another token for different resource like so:

$accessToken2 = $provider->getAccessToken('refresh_token', [
    'refresh_token' => $accessToken1->getRefreshToken(),
    'resource' => 'http://urlOfYourSecondResource'
]);

At the moment, there is one issue: When you make a call to your API and the token has expired, it will have the value of $provider->urlAPI which is obviously wrong for $accessToken2. The solution is very simple - set the $provider->urlAPI to the resource which you want to call. This issue will be addressed in future release. Please note that this is experimental and wasn't fully tested.

Known users

If you are using this library and would like to be listed here, please let us know!

Contributing

We accept contributions via Pull Requests on Github.

Credits

Support

If you find a bug or encounter any issue or have a problem/question with this library please create a new issue.

License

The MIT License (MIT). Please see License File for more information.

oauth2-azure's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oauth2-azure's Issues

Graph API Calls fail

With the latest Version 1.4.0, all Calls to /me via graph.windows.net fail with the Hint "a supported API Version must be provided".
I am not sure about the Purpose of the Changes of the \TheNetworg\OAuth2\Client\Provider\Azure in Lines 185ff, but these Changes are responsable for not appending the "?api-version=1.6" to the Graph API Calls anymore. When changing the "else" Branch to the old Version, everything works again.

Thanks,
Christoph

Support for client_assertion with certificate

Hi,

I recently needed to authenticate with Azure AD from PHP, using a client certificate.
It is using the proposed standard described here: https://tools.ietf.org/html/rfc7521
which basically is signing a JWT using the certificate and sending it to the OAuth endpoint.
My certificate is contained in a pfx file.

I could not find any code that supports this scenario, neither in this library or elsewhere.
So I went ahead and wrote the code myself, and it seems to be working.

Is this kind of code something that could be interesting to add to this library? I can do a pull request, but I just wanted to check if this is something you would want.

Class 'TheNetworg\OAuth2\Client\Provider\RuntimeException' not found

Getting this error with

Error in: ROOT/vendor/thenetworg/oauth2-azure/src/Provider/Azure.php, line 240

using RuntimeException from the root namespace fixes the error
change
throw new RuntimeException
to
throw new \RuntimeException

Also my Application Id is found in the appid claim while aud contains https://graph.windows.net/
changing the token claim check on line 239 from aud to appid allows the token to be validated correctly

Automatic Refresh Token not working

In Azure.php at the request function a $app variable is referenced, but it is never declared.

if ($accessToken->hasExpired()) { $accessToken = $app->OAuth2->provider->getAccessToken('refresh_token', [ 'refresh_token' => $app->OAuth2->token->getRefreshToken(), 'resource' => $this->urlAPI ]); }

I fixed it with a reference to $this and to $accessToken, since we are already in the provider class.

if ($accessToken->hasExpired()) { $accessToken = $this->getAccessToken('refresh_token', [ 'refresh_token' => $accessToken->getRefreshToken(), 'resource' => $this->urlAPI ]); }

Also for the Office365 API (outlook.office.com) you are not allowed to send a 'resource' field. Ist the Office365 API not in the Scope of this project or just not implemented yet?

Error: Azure Class not found

Hi! I'm new with azure ad so I'm not really well-versed with this subject.

I have done the install by using composer
-composer require league/oauth2-client
-composer require thenetworg/oauth2-azure

When i run the Authorization code flow i get the error:
Fatal error: Class 'TheNetworg\oauth2\src\Provider\Azure' not found in C:\wamp\www\Auth_Azure\vendor\try.php on line 3

I only rewrote the parts which concern my connection.

Did i do something bad? Did i miss something? If you have an idea please?

Resource owner

Shouldn't the method be something like:

    public function getResourceOwnerDetailsUrl(AccessToken $token)
    {
        return "https://graph.windows.net/me?api-version=1.6";
    }

This would make if work by:

$me = $provider->getResourceOwner($token);

getResponse() no longer compatible with this provider

getResponse() no longer returns a parsed response. It now returns an unparsed PSR-7 instance and provider no longer works as of version 1.3.

OAuth client 2.0.0 renamed getResponse() to getParsedResponse().
https://github.com/thephpleague/oauth2-client/blob/master/CHANGELOG.md#200

Since you updated lib requirements, it broke the provider because it's unable to parse the response.

Please update all instances of getResponse to getParsedResponse.

#32

Oauth2-client deprecated warning on PHP 7.1

I've been checking comparability with PHP 7.1 for our web app, which runs in a set of Docker containers, and I've noticed that the RandomFactory functions in oauth2-client have been replaced by native random functions as of version 2.0 . Would it be possible for you to bump the version in this library (and/or your own 2.0 branch) to version 2.0+ of oauth2-client, or are there BC breaks?

Obviously it's not an imminent priority, but future proofing is good!

how to change/update password?

Hi
In php
In Edit user there is no field for update password.
how can i update password using graph api.

Thanks
ikhlas

accesstoken can reuse ?

I login 1 account and can get access_token .
$accessToken = $token->getToken();
$refreshToken = $token->getRefreshToken();

I can get profile from $token object
$this->_provider->get("me", $token);

After i store 2 string (accessToken, refreshToken) in db
Now, i want to reuse access token to get profile. But not working, because accessToken is string, not \League\OAuth2\Client\Token\AccessToken.

Show error "Call to a member function hasExpired() on string"

So, plz help me get $token object from accessToken string ?

Unauthorized

Hello!

I am getting the next error:

Graph returned error: Unauthorized

On the callback url:

http://domain.com?code=AQABAAIAAADX8GCi6Js6SK82TsD2Pb7rJcpKEt4EUGFlNQuDZuugG4k0CF0QrSChW9EHVG7ODl9Pkr9no7ILKI5FJI2z9eDVPZ5l1HsGMXSAoaIm-tdKfNC9zV8MnDLKz7H5qZQI030H2q6Kfxq0fM9ZOcFAHJDnkkq-9ydTmpcsNUiLz_99bIQc__4ObwiqNbXLEtteAu4AVI1rpxHTJSmmct2B-LJj1S4_T06s1iZj5O8qP07d8X_QNdNDdEo_AsyN-LhxZKaP24x3qgoSRPryxldStiBl_Dsxzg9xzAE3_5idig6N6dFzuDppe-uS4zX2hAYcjy6qs1Hfa3fjwICXmGq5s49Wu4I81dRrmDMKb5KCXll-iunNPbTwFuP96P6rW9w_sW1VG_50PcFmy1Ex6B7RfFEfXUGxUANli51SStAlhNzkqXyI89tRedDZRF0LbJXm5MFbMWmUbS6ib6sEIQo3DrRdAlEe60AoSwjGd50IZwWun0iiNIYsE2LmGBe_ZW_x2y9x_aYxmSYK06pNYliqOdpZe5PT9v4hv67yw7E970-ESb_GN1v-LL_ZzCs-CdMvD9xjw0wgYFS5r5ZMKfZosgeJIAA&state=61e804bb5e3c8fc10e738315fb6ce923&session_state=bc502bf0-706b-4e35-bd92-112f191843b4

My code is:

public function loginVerifier($code)
{
try {
$provider = $this->connect($this->azureClientId, $this->azureClientSecret);
$token = $provider->getAccessToken('authorization_code', [
'code' => $code,
'resource' => 'https://graph.windows.net',
]);

    } catch(\Exception $e) {
        echo 'Graph returned an error: ' . $e->getMessage();
        exit;
    }

    return $token;
}

I tested withe 'resource' => 'https://graph.microsoft.com', too, but i get the same response.

Can you help me please?

Best regards!

League\\OAuth2\\Client\\Provider\\Exception\\IdentityProviderException

Hi, i'm trying to get photo from microsoft graph, and need microsoftgraph accessToken ..

Here is the code that I'm using:

            $headers = $request->header('Authorization');
            $provider = new Azure($this->userConfig);
            $authorization = explode(' ', $headers);
            $accessToken = $authorization[1];

$graphAccessToken = $provider->getAccessToken('jwt_bearer', [
                'resource' => 'https://graph.microsoft.com/v1.0/',
                'assertion' => $accessToken,
                'requested_token_use' => 'on_behalf_of'
            ]);

            $me = $provider->get('https://graph.microsoft.com/v1.0/me/photo/$value', $graphAccessToken);
            print_r($me);

but i'm get bad Request response at: League\OAuth2\Client\Provider\Exception\IdentityProviderException
any solutions?

Many thanks,

PHP 5.5 Not Supported

The composer.json for this repo lists "php": ">=5.5.0", but "league/oauth2-client": "~2.0" only supports >= 5.6.0.

Composer complains when trying to install in a 5.5 project.

composer install fails on v2.0.0 branch

Hi,

We have been using the v2.0.0 branch and noticed that the composer is failing because of missing requirement

Problem 1
    - Installation request for thenetworg/oauth2-azure 2.0.0.x-dev -> satisfiable by thenetworg/oauth2-azure[v2.0.0.x-dev].
    - thenetworg/oauth2-azure v2.0.0.x-dev requires gree/jose ^2.1 -> no matching package found.

Can you take a look at it and see if you are using that library?

Kanhai

api-version parameter being passed to Microsoft Graph

Hi,

Thanks for the great library. I've encountered a small issue when making calls to the Microsoft Graph API - see Stack Overflow here. I see you've recently changed part of the request function in #11, but that doesn't seem to have made any difference.

The fix seems fairly simple; to not append the api-version parameter on the MS Graph, (although they shouldn't be spitting out malformed JSON no matter what...) but I didn't want to do it myself via pull request without checking first whether you mind adding a hard-coded check for something like that.

Can I use this to retrive an access token using a users username/password?

I have an CRM API Server (Built in Laravel) which needs to login and get users emails and allocate them to a project on the server. I'll also need to generate contact list for the users which will sync with 365.

I have these functions working with Microsoft\Graph however, I need to automate these processes in a cron job, so what I need is for the API server to login to an account without user interaction and process the mail etc.

I have it working with League\OAuth2 but I'm using the flow where I get redirected to MS and enter the account details. I need to eliminate that step. I was looking at the 'Authorization Code Grant Flow' on here but I'm not sure if that's the right direction.

Apologies for posting a question in issues, I've been reading documentation and trying things for days and I just cant suss it out.

Regards

Louis

Uncaught exception 'League\OAuth2\Client\Provider\Exception\IdentityProviderException' with message 'Unauthorized'

I'm getting this error trying to connect to a Microsoft Dynamics API, originally tried the Microsoft provider, but that was the giving the same message and was pointed in this direction for Azure provider, but get the same message :

Fatal error: Uncaught exception 'League\OAuth2\Client\Provider\Exception\IdentityProviderException' with message 'Unauthorized' in C:\xampp\htdocs\apps\vendor\thenetworg\oauth2-azure\src\Provider\Azure.php:68 Stack trace: #0 C:\xampp\htdocs\apps\vendor\league\oauth2-client\src\Provider\AbstractProvider.php(613): TheNetworg\OAuth2\Client\Provider\Azure->checkResponse(Object(GuzzleHttp\Psr7\Response), Array) #1 C:\xampp\htdocs\apps\vendor\league\oauth2-client\src\Provider\AbstractProvider.php(528): League\OAuth2\Client\Provider\AbstractProvider->getParsedResponse(Object(GuzzleHttp\Psr7\Request)) #2 C:\xampp\htdocs\apps\vendor\thenetworg\oauth2-azure\src\Provider\Azure.php(54): League\OAuth2\Client\Provider\AbstractProvider->getAccessToken('authorization_c...', Array) #3 C:\xampp\htdocs\apps\test_dynamics_api.php(98): TheNetworg\OAuth2\Client\Provider\Azure->getAccessToken('authorization_c...', Array) #4 {main} thrown in C:\xampp\htdocs\apps\vendor\thenetworg\oauth2-azure\src\Provider\Azure.php on line 68

Any suggestions?
I'm getting a code back, but this error happens when it tries to get a token..

        // Try to get an access token (using the authorization code grant)
        $token = $provider->getAccessToken('authorization_code'...................

Composer install not keeping up with git

When I replace the vendor/thenetworg/oauth2-azure/src folder with a git cloned folder, all the errors go away (and I get a logout function). Things are not synced. Is there something you can do from here?
-git newb

Invalid audience?

So I'm trying to integrate oauth with my app and I'm having some issues. I have the app registered in the portal and have verified my app id and secret. I'm able to sign on to AAD but when I get sent to the callback I get Uncaught RuntimeException: The audience is invalid!

The error is occurring in AccessToken.php on line 42

Here is the code for my callback page (the tokens and such are drawn from a config database, I've verified that the data is being presented appropriately).

https://gist.github.com/domkirby/960b64c85c0223d9a2cde25d4c7378ce

v2.0.0

List of features to be added into v2.0.0 version.

  • Make use of https://login.microsoftonline.com/TENANT/.well-known/openid-configuration endpoint
  • Implement caching of the configuration settings.
    • Default directory is going to be obtained by sys_get_temp_dir and will be changeable in configuration
  • Check on token issuer validation with validateIssuer
  • Fix getObjects to also include $tenant in subsequent requests (if odata.nextLink is not a valid URL)
  • Fix support for B2C
    • Replace $provider->appendQuery with our own method to check if we are already appending to existing parameters
  • Improve documentation
    • Multipurpose refresh tokens
    • Documentation for response_mode and response_type options
    • Make use of GitHub's Wiki
    • Single Sign Out documentation (866b5a0)
  • Evaluate migration scenarios

Issue with Resource ID not getting passed into Auth URL

I am attempting to authenticate a Dynamics 365 Web API endpoint via your AzureAD library and am running into issues. I believe it is because the Resource ID is not passed as a query parameter in the Auth Url (not 100% certain on this though). It does not appear the resource is getting accounted anywhere in my token request.

Unable to issue tokens

Sign in

Sorry, but we’re having trouble signing you in.

AADSTS50020: We are unable to issue tokens from this API version for a Microsoft account. Please contact the application vendor as they need to use version 2.0 of the protocol to support this.

https://prnt.sc/l18lqa

Fatal error with branch v2.0.0

Hi There,

I'm trying to use branch v2.0.0 but have an issue with the following error:

Fatal error: Uncaught Error: Cannot use object of type GuzzleHttp\Psr7\Response as array in /var/www/html/foo/bar/vendors/thenetworg/oauth2-azure/src/Provider/Azure.php:51

My code is:

$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
  'clientId' => 'x',
  'clientSecret' => 'x',
  'redirectUri' => 'https://domain.com/',
  'metadata' => 'https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration',
  'responseType' => 'id_token',
  'responseMode' => 'form_post',
]);
$authUrl = $provider->getAuthorizationUrl();

Am I using it correctly - any advice on how to resolve?

Thanks

checkResponse gets error message as an array

Problem:

Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]]) in [vendor/league/oauth2-client/src/Provider/Exception/IdentityProviderException.php, line 36]

Cause:

    protected function checkResponse(ResponseInterface $response, $data)
    {
        if (isset($data['odata.error'])) {
            if (isset($data['odata.error']['message'])) {
                $message = $data['odata.error']['message']; // <-----
            }

Because:

data['odata.error']['message'] = Array
(
    [lang] => en
    [value] => The specified api-version is invalid. The value must exactly match a supported version.
)

Solution:

$message = $data['odata.error']['message']['value'];

Issue with GrantFactory

Opened a similar issue on the League's Oauth Client.. I'm seeing an issue with the GrantFactory. Not sure if its the GrantFactory that's not functioning or if its the call through the Azure Oauth2 client out to the league's client...

[11-Sep-2017 18:23:40 America/Denver] PHP Parse error: syntax error, unexpected
'class' (T_CLASS), expecting identifier (T_STRING) or variable (T_VARIABLE) or
'{' or '$' in /#####/#######/public_html/azuretest/vendor/league/oauth2-client/
src/Grant/GrantFactory.php on line 85

I installed tonight so it grabbed the latest available from The League. Haven't had a chance to try an earlier release yet.

How to restore token object from access_code

Maybe I'm looking in the wrong direction, but how would one go about to restore the token object from an access_code in storage (say in a session). It looks like the public function validateAccessToken in Azure.php is the right candidate, but it throws an error

Undefined variable: provider Fatal error: Call to a member function getClientId() on null in D:\home\site\vendor\thenetworg\oauth2-azure\src\Provider\Azure.php on line 237

Am I missing something?

-- UPDATE:
Nevermind, figured out I can leverage the new \League\OAuth2\Client\Token\AccessToken class for this.

getClaim does not exist as per documentation

The documentation states:
getClaim($name) - Gets any other claim (specified as $name) from the JWT, full list can be found here

This method doesn't actually exist, you need to do claim($name)

echo 'Hello, '.$resourceOwner->claim("name").'!';

Call to undefined function getAccessTokenFromYourDataStore()

Hi! Yeah another question already. Igot everything to work and after identification i go back on another page where i'm trying to get back the token to get user information but when i use this code i get the error Call to undefined function getAccessTokenFromYourDataStore().
I think i need to add an import but i'm not sure about it. Any ideas please?
Here is the code i'm using on my second page.

<?php
//require_once('AccessToken.php');
require __DIR__ . '/vendor/autoload.php';
$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
    'clientId'          => '',
    'clientSecret'      => '',
    'redirectUri'       => 'http://localhost/Co_Azure/index.php',
    'resource' => 'https://management.azure.com/'
]);


$existingAccessToken = getAccessTokenFromYourDataStore();

if ($existingAccessToken->hasExpired()) {
    $newAccessToken = $provider->getAccessToken('refresh_token', [
        'refresh_token' => $existingAccessToken->getRefreshToken()
    ]);

    // Purge old access token and store new access token to your data store.
}
$resourceOwner = $provider->getResourceOwner($existingAccessToken);
echo 'Hello, '.$resourceOwner->getFirstName().'!';
?>

Error in v.2.0.0 branch : OpenSSL unable to verify data

Hi,

Today suddenly I am getting below error after updating files from composer. When I try to login through oauth2, it gives me below error.

OpenSSL unable to verify data: error:0906D06C:PEM routines:PEM_read_bio:no start line
#0 /var/app/current/application/vendor/firebase/php-jwt/src/JWT.php(96): Firebase\JWT\JWT::verify('eyJ0eXAiOiJKV1Q...', 'Q\xFE\xBB\ns&\xA7\xA1Cy\xC2\xB6\xF7\xEFk...', '-----BEGIN PUBL...', 'RS256') 
#1 /var/app/current/application/vendor/thenetworg/oauth2-azure/src/Provider/Azure.php(297): Firebase\JWT\JWT::decode('eyJ0eXAiOiJKV1Q...', Array, Array) 
#2 /var/app/current/application/vendor/thenetworg/oauth2-azure/src/Token/AccessToken.php(64): TheNetworg\OAuth2\Client\Provider\Azure->validateToken('eyJ0eXAiOiJKV1Q...') 
#3 /var/app/current/application/vendor/thenetworg/oauth2-azure/src/Provider/Azure.php(122): TheNetworg\OAuth2\Client\Token\AccessToken->__construct(Array, Object(TheNetworg\OAuth2\Client\Provider\Azure)) 
#4 /var/app/current/application/vendor/league/oauth2-client/src/Provider/AbstractProvider.php(561): TheNetworg\OAuth2\Client\Provider\Azure->createAccessToken(Array, Object(League\OAuth2\Client\Grant\AuthorizationCode)) 
#5 /var/app/current/application/vendor/thenetworg/oauth2-azure/src/Provider/Azure.php(70): League\OAuth2\Client\Provider\AbstractProvider->getAccessToken('authorization_c...', Array) #6 /var/app/current/application/controllers/Openauth.php(156): TheNetworg\OAuth2\Client\Provider\Azure->getAccessToken('authorization_c...', Array) 
#7 [internal function]: Openauth->validate_office() 
#8 /var/app/current/system/core/CodeIgniter.php(514): call_user_func_array(Array, Array) 
#9 /var/app/current/index.php(291): require_once('/var/app/curren...') 
#10 {main}

Till yesterday it was running fine. I was able to login successfully. Can you please check what is the issue.

Kanhai

PHP Fatal error

Class TheNetworg\OAuth2\Client\Provider\AzureResourceOwner contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (League\OAuth2\Client\Provider\ResourceOwnerInterface::toArray) in [vendor/thenetworg/oauth2-azure/src/Provider/AzureResourceOwner.php, line 35]

MFA Support

My company had setup MFA location/device based.
When we are outside office with an unknown device, Azure requires MFA to be accessed.
The code you provided as example for logins exits in the Incorrect state condition right after login, not going through required device authentication (as example with Code or a Call).
You're library support this situation? Do you have some sample code of how to redirect to device authorization page or can you point me to some documentation?
Thanks

Add alias for email in Resource Owner

Is there any harm adding getEmail as an alias of the upn claim?

Almost every oauth client packages implements getEmail so it would be useful to just have that available.

OpenSSL unable to verify data: error:04091068:rsa routines:INT_RSA_VERIFY:bad signature

Hi,

When I try to use any Graph resource I get following error:

OpenSSL unable to verify data: error:04091068:rsa routines:INT_RSA_VERIFY:bad signature

the resource URL that I'm using is https://graph.microsoft.com/

I set the provider configuration as is explained in the documentation, but keeps failing.

Here is the code that I'm using:

   $settings = [
        'clientId'                  => config('azure.azureKey'),
        'clientSecret'              => config('azure.azureSecret'),
        'redirectUri'               => config('azure.azureRedirectUri')
    ];

    //$provider = new OAuth2Provider($settings);
    $provider = new AzureProvider($settings);
    $provider->scope = 'calendars.read';
    $provider->urlAPI = "https://graph.microsoft.com/v1.6/";
    $provider->resource = "https://graph.microsoft.com/";

If I use https://graph.windows.net as the resource, the token is correctly validated.

Thanks in advance!

Improve security for the token flow and add Web API protection

As per @vibronet's comments during BUILD 2016, the following improvements will be made in order to comply with security requirements on Azure AD/OpenID.
This also requires different AccessToken class handling as described in thephpleague/oauth2-client#513.

  • Always validate the id_token signature
    • When we obtain new access_token, id_token is provided as well. The signature should be always validated whenever constructing the AccessToken object instead of checking it when calling $provider->getResourceOwner($token);. If invalid, an exception should be returned.
    • At the moment, the resource owner is obtained from the access_token which is wrong due to the fact, that with the 2.0 Azure AD authentication endpoints, it is not guaranteed that the access_token is still going to be a JWT (as per @vibronet's advice during BUILD 2016).
  • Always validate following id_token claims
    • Audience (aud) claim - to verify that the id_token was intended to be given to your app
    • Not Before (nbf) and Expiration Time (exp) claims - to verify that the id_token has not expired
    • Issuer (iss) claim - to verify that the token was indeed issued to your app
      • This also requires the ability to turn off the validation and use a custom one when multitenant (/common/ endpoint) application scenario is used
      • In case of a single tenant application in use with v2.0 endpoint, it will also allow for easier tenant filtering.
  • Ability to protect your web API with this library - going to introduce a function like validateAccessToken($token) which is going to return either the parsed token which your app received or throw an exception with the error.
  • Add documentation and example of protecting your Web API with validateAccessToken($token)
  • Add support for urn:ietf:params:oauth:grant-type:jwt-bearer grant type (use setGrant to register it), also reflect it in the README.md
    • Will be added as TheNetworg\OAuth2\Client\Grant\JwtBearer for shorter name and referenced as jwt_bearer in $provider->getAccessToken(...)
  • Add method $provider->getLogoutUrl($post_logout_redirect_uri) to make logging out more streamlined.
    • Implement
    • Add documentation to README.md
  • Update composer.json to support version 1.4.0 and higher of thephpleague/oauth2-client

The full implementation is going to require quite a lot of testing, because this could potentially break plenty of things if implemented wrong, so it might take a while before it gets released.

Uncaught exception 'GuzzleHttp\Exception\RequestException' with message 'cURL error 60: SSL certificate problem: unable to get local issuer certificate

Hi!
I'm getting the error Uncaught:
exception 'GuzzleHttp\Exception\RequestException' with message 'cURL error 60: SSL certificate problem: unable to get local issuer certificate

I'm running the following code:

<?php
session_start();
require __DIR__ . '/vendor/autoload.php';

$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
    'clientId'          => '41bb2d7f-c75d-4866-a659-ba5103f0738d',
    'clientSecret'      => 'pqlfDVOQ49eaoXMO402~|]]',
    'redirectUri'       => 'http://localhost/Co_Azure/index.php',
    'resource' 			=> 'https://management.azure.com/'
]);

 $token = $provider->getAccessToken('authorization_code', [
        'code' => $_GET['code'],
        'resource' => 'https://graph.windows.net',
    ]);


$me = $provider->get("me", $token);

        // Use these details to create a new profile
echo $me['givenName'];
?>

I tried to:
Download the latest cacert.pem from https://curl.haxx.se/ca/cacert.pem and add the following line to php.ini: curl.cainfo="/path/to/downloaded/cacert.pem"
But it doesn't get better. Did you get the same problem?

Access Token Validation Failure switching resource [v2.0.0]

Hi Jan - I'm coming across an issue that I'm struggling to resolve. The code below has functioned perfectly for 2yrs using v1.x of oauth2-azure alongside v1.4.1 of league/oauth2-client with PHP5.6

I've now upped to PHP7.1 - this causes a pile of deprecation warnings due to league/oauth2-client's use of ircmaxell/random-lib, so upgraded league/oauth2-client to v2.0.0 (which uses paragonie, thus resolving the deprecation warnings), and then upgraded thenetworg/oauth2-azure to v2.0.0

Now the code below fails with 'Access Token Validation Failure' thrown at line63 - $provider->get($provider->urlAPI . '/beta/me', $_SESSION["MyApp"]['refresh_token'])

If I immediately switch back to v1.x of both, all works.

 $provider = new TheNetworg\OAuth2\Client\Provider\Azure(
    [
        'clientId'          => $app->clientId,
        'clientSecret'      => $app->clientSecret,
        'redirectUri'       => $app->redirectUri
    ]
);
if (!isset($_GET['code']) && !isset($_SESSION["MyApp"]['refresh_token'])) {
    // We're not auth'd. Let's auth.
    unset($_SESSION["MyApp"]['my']);

    $authUrl = $provider->getAuthorizationUrl();
    $_SESSION["MyApp"]['oauth2state'] = $provider->getState();
    header('Location: '.$authUrl);
    exit;
} elseif (!isset($_SESSION["MyApp"]['refresh_token']) && (empty($_GET['state']))) {
    // We've hit an invalid / inconsistent state - CSRF? Either way, reauth.
    unset($_SESSION["MyApp"]['oauth2state']);

    $authUrl = $provider->getAuthorizationUrl();
    header('Location: '.$authUrl);
    exit;
} else {

    $invalid = 0;

    // We authenticated... get a token.
    if (!isset($_SESSION["MyApp"]["refresh_token"])) {

        $token = $provider->getAccessToken(
            'authorization_code', [
                'code' => $_GET['code'],
                'resource' => 'https://graph.windows.net/',
            ]);

        // Get a refreshToken for the Graph API
        $_SESSION["MyApp"]["refresh_token"] = $provider->getAccessToken(
            'refresh_token', [
                'refresh_token' => $token->getRefreshToken(),
                'resource' => 'https://graph.microsoft.com/'
            ]);
    } else {
        $token = $_SESSION["MyApp"]["refresh_token"];
        $time = time();
        if (($token->getExpires()) - $time < 600) {
            $invalid = 1;
        }
    }

    try {
        if ($invalid == 1) {
            $_SESSION["MyApp"]['refresh_token'] = $provider->getAccessToken(
                'refresh_token', [
                    'refresh_token' => $token->getRefreshToken(),
                    'resource' => 'https://graph.microsoft.com'
                ]
            );
        }

        $provider->urlAPI = 'https://graph.microsoft.com';

        // Get user characteristics from Azure AD...
        $my = (!isset($_SESSION["MyApp"]['my'])) ? $provider->get($provider->urlAPI . '/beta/me', $_SESSION["MyApp"]['refresh_token']) : $_SESSION["MyApp"]['my'];  // <-- being line 63 of auth.php mentioned below
    }
}

Stack Trace:

Error: Access token validation failure.
File: /home/myapp/public_html/vendor/thenetworg/oauth2-azure/src/Provider/Azure.php
Line: 107
Trace: League\OAuth2\Client\Provider\Exception\IdentityProviderException: Access token validation failure.
   at TheNetworg.OAuth2.Client.Provider.Azure.checkResponse(Azure.php:107)
   at League.OAuth2.Client.Provider.AbstractProvider.getResponse(AbstractProvider.php:644)
   at TheNetworg.OAuth2.Client.Provider.Azure.request(Azure.php:233)
   at TheNetworg.OAuth2.Client.Provider.Azure.get(Azure.php:177)
   at (main)(auth.php:63)

I have already checked instructions at https://github.com/TheNetworg/oauth2-azure/tree/v2.0.0#microsoft-graph and tried amending code to...

$provider->urlAPI = 'https://graph.microsoft.com/';
$provider->resource = "https://graph.microsoft.com/";
$my = (!isset($_SESSION["MyApp"]['my'])) ? $provider->get('beta/me', $_SESSION["MyApp"]['refresh_token']) : $_SESSION["MyApp"]['my'];

...but this then throws League\OAuth2\Client\Provider\Exception\IdentityProviderException: Invalid domain name in the request url.

Any suggestions on what I'm missing to move up to v2.0.0 successfully?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.