All Projects → TheNetworg → Oauth2 Azure

TheNetworg / Oauth2 Azure

Licence: mit
Azure AD provider for the OAuth 2.0 Client.

Projects that are alternatives of or similar to Oauth2 Azure

Vscode Apimanagement
VS Code extension for Azure API Management.
Stars: ✭ 32 (-77.14%)
Mutual labels:  azure, microsoft
Azuremonitoringhackathon
Operationalize Azure deployments with Azure platform tools​
Stars: ✭ 46 (-67.14%)
Mutual labels:  azure, microsoft
Partnercenterpowershellmodule
Partner Center PowerShell Module
Stars: ✭ 35 (-75%)
Mutual labels:  azure, microsoft
Azure Core Concepts Book
A curated guide to get going fast on the Azure platform. Links, best-practices, explanations and comments, I wish I had known before I started using Azure.
Stars: ✭ 17 (-87.86%)
Mutual labels:  azure, microsoft
Recommenders
Best Practices on Recommendation Systems
Stars: ✭ 11,818 (+8341.43%)
Mutual labels:  azure, microsoft
Azure Openshift
RedHat Openshift Origin cluster on Azure
Stars: ✭ 17 (-87.86%)
Mutual labels:  azure, microsoft
Computervision Recipes
Best Practices, code samples, and documentation for Computer Vision.
Stars: ✭ 8,214 (+5767.14%)
Mutual labels:  azure, microsoft
Azure Iot Sdk C
A C99 SDK for connecting devices to Microsoft Azure IoT services
Stars: ✭ 412 (+194.29%)
Mutual labels:  azure, microsoft
Azure
Azure-related repository
Stars: ✭ 78 (-44.29%)
Mutual labels:  azure, microsoft
Architecture Center
Azure Architecture Center
Stars: ✭ 1,207 (+762.14%)
Mutual labels:  azure, microsoft
Azuredatastudio
Azure Data Studio is a data management tool that enables working with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux.
Stars: ✭ 6,605 (+4617.86%)
Mutual labels:  azure, microsoft
Azure Event Hubs For Kafka
Azure Event Hubs for Apache Kafka Ecosystems
Stars: ✭ 124 (-11.43%)
Mutual labels:  azure, microsoft
Azure Design
Here you will find my complete Azure Visio Stencil and bonus SVG and PNG versions for all of the Azure Service and configuration items.
Stars: ✭ 470 (+235.71%)
Mutual labels:  azure, microsoft
Cloud Integration Beta
Docker CLI with ACI integration (beta)
Stars: ✭ 29 (-79.29%)
Mutual labels:  azure, microsoft
Cli Microsoft365
Manage Microsoft 365 and SharePoint Framework projects on any platform
Stars: ✭ 420 (+200%)
Mutual labels:  azure, microsoft
Pci Paas Webapp Ase Sqldb Appgateway Keyvault Oms
Azure PCI PaaS Reference Architecture
Stars: ✭ 36 (-74.29%)
Mutual labels:  azure, microsoft
Azure Iot Sdk Python
A Python SDK for connecting devices to Microsoft Azure IoT services
Stars: ✭ 261 (+86.43%)
Mutual labels:  azure, microsoft
Azure Spring Boot
Spring Boot Starters for Azure services
Stars: ✭ 352 (+151.43%)
Mutual labels:  azure, microsoft
Private Aks Cluster
This sample shows how to create a private AKS cluster in a virtual network along with a jumpbox virtual machine.
Stars: ✭ 63 (-55%)
Mutual labels:  azure, microsoft
Azops
This container image can be used to deploy ARM templates at Tenant, Management Group, Subscription and Resource Group scope and export current Azure configuration hierarchy in Git repository.
Stars: ✭ 109 (-22.14%)
Mutual labels:  azure, microsoft

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
    '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.

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
$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.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].