PHPackages                             untt/oauth2-microsoft - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. untt/oauth2-microsoft

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

untt/oauth2-microsoft
=====================

Microsoft OAuth2 Provider for The PHP League OAuth2 Client

0.0.3(2mo ago)238GPL-3.0-or-laterPHPPHP ^8.2CI passing

Since Feb 13Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/tunterreitmeier/oauth2-microsoft)[ Packagist](https://packagist.org/packages/untt/oauth2-microsoft)[ RSS](/packages/untt-oauth2-microsoft/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (8)Versions (7)Used By (0)

Microsoft OAuth2 Provider for PHP League OAuth2 Client
======================================================

[](#microsoft-oauth2-provider-for-php-league-oauth2-client)

[![CI](https://github.com/tunterreitmeier/oauth2-microsoft/workflows/CI/badge.svg)](https://github.com/tunterreitmeier/oauth2-microsoft/actions)[![Latest Stable Version](https://camo.githubusercontent.com/54b23f65d97d5459af15c39020d2bd7d60f96912b4f110e6b1387233258959b7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f756e74742f6f61757468322d6d6963726f736f66742e737667)](https://packagist.org/packages/untt/oauth2-microsoft)[![License](https://camo.githubusercontent.com/593f78f34c9e25f47c2220e3a6209f258c14d3cfb663ec9c40ac22b30605e0b9/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f74756e746572726569746d656965722f6f61757468322d6d6963726f736f6674)](LICENSE)

A production-ready Microsoft OAuth2 provider package for [thephpleague/oauth2-client](https://github.com/thephpleague/oauth2-client), enabling authentication via Microsoft Entra (Azure AD) with support for both personal and organizational accounts.

Features
--------

[](#features)

- **Microsoft Graph API integration**: Fetches comprehensive user data from Microsoft Graph
- **Flexible tenant support**: Common, organizations-only, consumers-only, or specific tenant
- **OpenID Connect support**: Helper methods to access ID token claims

Requirements
------------

[](#requirements)

- PHP 8.2 or higher
- league/oauth2-client ^2.6.0

Installation
------------

[](#installation)

```
composer require untt/oauth2-microsoft
```

Usage
-----

[](#usage)

### Basic Usage

[](#basic-usage)

Default tenant is `common` which will work for both personal and work accounts.

```
use Unt\OAuth2\Client\Provider\MicrosoftProvider;

$provider = new MicrosoftProvider([
    'clientId'     => '{microsoft-client-id}',
    'clientSecret' => '{microsoft-client-secret}',
    'redirectUri'  => 'https://example.com/callback',
]);

// Get authorization URL
$authorizationUrl = $provider->getAuthorizationUrl();

// Save state for CSRF protection
$_SESSION['oauth2state'] = $provider->getState();

// Redirect user to authorization URL
header('Location: ' . $authorizationUrl);
exit;
```

### Handle Callback

[](#handle-callback)

```
// Verify state for CSRF protection
if (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
    unset($_SESSION['oauth2state']);
    exit('Invalid state');
}

try {
    // Get access token
    $token = $provider->getAccessToken('authorization_code', [
        'code' => $_GET['code']
    ]);

    // Get user details from Microsoft Graph API
    $resourceOwner = $provider->getResourceOwner($token);

    echo 'Hello, ' . $resourceOwner->getDisplayName() . '!';
    echo 'Email: ' . $resourceOwner->getEmail();
    echo 'User ID: ' . $resourceOwner->getId();

} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
    exit('Authentication failed: ' . $e->getMessage());
}
```

### Tenant Selection

[](#tenant-selection)

#### Organizations Only (Work/School Accounts)

[](#organizations-only-workschool-accounts)

```
use Unt\OAuth2\Client\Provider\MicrosoftProvider;

$provider = new MicrosoftProvider([
    'clientId'     => '{microsoft-client-id}',
    'clientSecret' => '{microsoft-client-secret}',
    'redirectUri'  => 'https://example.com/callback',
    'tenant'       => MicrosoftProvider::TENANT_ORGANIZATIONS,
]);
```

#### Specific Tenant

[](#specific-tenant)

```
$provider = new MicrosoftProvider([
    'clientId'     => '{microsoft-client-id}',
    'clientSecret' => '{microsoft-client-secret}',
    'redirectUri'  => 'https://example.com/callback',
    'tenant'       => '12345678-1234-1234-1234-123456789012', // Your tenant ID
]);
```

### Accessing ID Token Claims

[](#accessing-id-token-claims)

If you need access to the OpenID Connect ID token claims (e.g., tenant ID, authentication metadata), you can add them to the scopes.

```
// Request OpenID Connect scopes when getting authorization URL
use new \Unt\OAuth2\Client\Provider\MicrosoftProvider;

$authorizationUrl = $provider->getAuthorizationUrl([
    'scope' => array_merge(
        ['openid', 'profile', 'email']
        ['User.Read']
    )
]);

// or use helper method
$provider = (new MicrosoftProvider())->requireOpenIdScopes();

// After getting the access token
$token = $provider->getAccessToken('authorization_code', ['code' => $_GET['code']]);

// Decode ID token claims
$idToken = $provider->getIdTokenClaims($token);

echo 'Tenant ID: ' . $idToken->tenantId;
echo 'Name: ' . $idToken->name;
echo 'Username: ' . $idToken->preferredUsername;
echo 'Email: ' . $idToken->email;

// full token payload: $idToken->fullPayload
```

Please note that the OpenID Connect JWT is not actively verified. Just as with the Access Token, you should verify the `state` to detect forged requests.

### Additional Scopes

[](#additional-scopes)

Request additional Microsoft Graph API permissions:

```
$authorizationUrl = $provider->getAuthorizationUrl([
    'scope' => ['openid', 'User.Read', 'Calendars.Read', 'Mail.Read']
]);
```

Please note that Microsoft usually does not allow scopes across different 'product spaces'. So if you require for example `User.Read` from `https://graph.microsoft.com`, you will not be able to request `SMTP.Send`from `https://outlook.office.com` in the same token. You will have to request these individually, using a refresh token.

In Microsoft identity platform authorization, token, or consent requests, omitting the resource identifier in the scope parameter defaults to Microsoft Graph. For example, `User.Read` is treated as `https://graph.microsoft.com/User.Read`.

### Refresh Tokens

[](#refresh-tokens)

To get a refresh token, include the `offline_access` scope:

```
$authorizationUrl = $provider->getAuthorizationUrl([
    'scope' => ['openid', 'User.Read', 'offline_access']
]);

// Store the refresh token
$token->getRefreshToken();

// Later, refresh the token
if ($token->hasExpired()) {
    $newToken = $provider->getAccessToken('refresh_token', [
        'refresh_token' => $token->getRefreshToken()
    ]);

    // store the new refresh token, in case it also has expired
}
```

Resource Owner Methods
----------------------

[](#resource-owner-methods)

The `MicrosoftResourceOwner` object fetched from Microsoft Graph API provides:

MethodDescriptionExample Value`getId()`User unique identifier`"12345678-abcd-..."``getUserPrincipalName()`Email-like identifier`"user@company.com"``getDisplayName()`Full name`"John Doe"``getGivenName()`First name`"John"``getSurname()`Last name`"Doe"``getEmail()`Email address \*`"john@company.com"``getJobTitle()`Job title`"Software Engineer"``getOfficeLocation()`Office location`"Building 42"``getMobilePhone()`Mobile phone`"+1234567890"``getBusinessPhones()`List of phone numbers`["+1234567890"]``getPreferredLanguage()`Locale preference`"en-US"``toArray()`All data as array`array(...)`Testing
-------

[](#testing)

Run the test suite:

```
composer test           # Run PHPUnit tests
composer test-coverage  # Run tests with HTML coverage report
composer check:static   # Run static analysis (PHPStan level 8)
composer check:style    # Check code style (PSR-12)
composer fix:style      # Fix code style issues
composer check          # Run all checks (style, PHPStan, tests)
```

Contributing
------------

[](#contributing)

Contributions are welcome! Please fork and create a PR.

License
-------

[](#license)

GNU General Public License version 3 License. See [LICENSE](LICENSE) for details.

Resources
---------

[](#resources)

- [Microsoft Identity Platform Documentation](https://learn.microsoft.com/en-us/entra/identity-platform/)
- [Microsoft Graph API Documentation](https://learn.microsoft.com/en-us/graph/)
- [OAuth 2.0 and OpenID Connect on Azure AD](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols)
- [PHP League OAuth2 Client](https://github.com/thephpleague/oauth2-client)

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance84

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

3

Last Release

81d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ee6f5d26d48b4b7da9a9eb4ef3e02f00047e35d1a9a38b02e84ef7816684bcc7?d=identicon)[tunterreitmeier](/maintainers/tunterreitmeier)

---

Top Contributors

[![tunterreitmeier](https://avatars.githubusercontent.com/u/26880534?v=4)](https://github.com/tunterreitmeier "tunterreitmeier (16 commits)")

---

Tags

clientoauthoauth2microsoftauthorizationazureentra

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/untt-oauth2-microsoft/health.svg)

```
[![Health](https://phpackages.com/badges/untt-oauth2-microsoft/health.svg)](https://phpackages.com/packages/untt-oauth2-microsoft)
```

###  Alternatives

[thenetworg/oauth2-azure

Azure Active Directory OAuth 2.0 Client Provider for The PHP League OAuth2-Client

2509.6M48](/packages/thenetworg-oauth2-azure)[league/oauth2-google

Google OAuth 2.0 Client Provider for The PHP League OAuth2-Client

41721.2M118](/packages/league-oauth2-google)[stevenmaguire/oauth2-keycloak

Keycloak OAuth 2.0 Client Provider for The PHP League OAuth2-Client

2275.9M27](/packages/stevenmaguire-oauth2-keycloak)[stevenmaguire/oauth2-microsoft

Microsoft OAuth 2.0 Client Provider for The PHP League OAuth2-Client

742.3M12](/packages/stevenmaguire-oauth2-microsoft)[patrickbussmann/oauth2-apple

Sign in with Apple OAuth 2.0 Client Provider for The PHP League OAuth2-Client

1132.5M6](/packages/patrickbussmann-oauth2-apple)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
