Skip to content

Commit 3c0a9a3

Browse files
author
enrico.degaudenzi@connectorly.io
committed
#553 Created Da\User\AuthClient\Microsoft365 auth client
1 parent 3633402 commit 3c0a9a3

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed

src/User/AuthClient/Microsoft365.php

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the 2amigos/yii2-usuario project.
5+
*
6+
* (c) 2amigOS! <http://2amigos.us/>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace Da\User\AuthClient;
13+
14+
use Da\User\Contracts\AuthClientInterface;
15+
use Da\User\Traits\AuthClientUserIdTrait;
16+
use yii\authclient\OAuth2;
17+
18+
/**
19+
* Microsoft365 allows authentication via Microsoft365 OAuth2 flow.
20+
* Before using Microsoft365 OAuth2 you must register your Microsoft Azure Application
21+
* @see https://portal.azure.com
22+
*
23+
* Note: the registered App must have the following:
24+
* -Authentication: 'Redirect URIs' set 'user/security/auth?authclient=microsoft365' as an absolute URL
25+
* e.g. https://domain.com/index.php/user/security/auth?authclient=microsoft365
26+
* -API Permissions: 'Microsoft Graph' > 'User.Read'
27+
* -Decide whether the App should be
28+
* single-tenant (only allow one Company to use it),
29+
* multi-tenant (also allow other Companies to use it),
30+
* personal account (allow accounts like xbox, skype etc. to use it)
31+
* or both "multi-tenant and personal-account"
32+
* -In the Microsoft world even the Authorization URls are different dendinding if you allow single/multi/personal accounts.
33+
* This client supports them: just set up the 'signInAudience' property (value for this it's in the manifest of your Azure App)
34+
* accordingly to your needs; it defaults to the widest permissions available "AzureADandPersonalMicrosoftAccount"
35+
* (details: https://learn.microsoft.com/en-us/entra/identity-platform/supported-accounts-validation)
36+
*
37+
* Example application configuration:
38+
*
39+
* ```
40+
* 'components' => [
41+
* ...
42+
* 'authClientCollection' => [
43+
* 'class' => 'yii\authclient\Collection',
44+
* 'clients' => [
45+
* 'microsoft365' => [
46+
* 'class' => 'yii\authclient\clients\Microsoft365',
47+
* 'clientId' => 'a5e19acd-dc50-4b0a-864a-d13b9347ddf9',
48+
* 'clientSecret' => 'ljSAd89.lvk34NV-3t4v3_2kl_42Rt4klr234',
49+
* 'signInAudience' => 'AzureADandPersonalMicrosoftAccount',
50+
* ],
51+
* ],
52+
* ]
53+
* ...
54+
* ]
55+
* ```
56+
*/
57+
class Microsoft365 extends OAuth2 implements AuthClientInterface
58+
{
59+
use AuthClientUserIdTrait;
60+
61+
public const ACCOUNT_TYPE_SINGLETENANT = 'AzureADMyOrg'; // Accounts in this organizational directory only (Single tenant)
62+
public const ACCOUNT_TYPE_MULTITENANT = 'AzureADMultipleOrgs'; // Accounts in any organizational directory (Any Microsoft Entra directory - Multitenant)
63+
public const ACCOUNT_TYPE_MULTITENANTANDPERSONAL = 'AzureADandPersonalMicrosoftAccount'; // Accounts in any organizational directory (Any Microsoft Entra directory - Multitenant) and personal Microsoft accounts (such as Skype, Xbox)
64+
public const ACCOUNT_TYPE_PERSONAL = 'PersonalMicrosoftAccount'; // Personal Microsoft accounts only
65+
66+
/**
67+
* @var string Micrososft365 Graph API endpoint.
68+
*/
69+
public $apiBaseUrl = 'https://graph.microsoft.com/v1.0';
70+
71+
/**
72+
* @var string 'signInAudience' in Microsoft Azure App manifest
73+
*/
74+
public $signInAudience;
75+
76+
/**
77+
* {@inheritdoc}
78+
*/
79+
public function init()
80+
{
81+
parent::init();
82+
83+
if (is_null($this->scope)) {
84+
$this->scope = 'User.Read';
85+
}
86+
87+
if (is_null($this->signInAudience)) {
88+
$this->signInAudience = self::ACCOUNT_TYPE_MULTITENANTANDPERSONAL;
89+
}
90+
91+
// In the Microsoft world Authorization URls are different if you use single-tenant or multi-tenant (@see https://learn.microsoft.com/en-us/entra/identity-platform/supported-accounts-validation)
92+
// This OAuth2 client supports also these scenarios: just set up 'signInAudience' accordingly to your needs. It defaults to the widest "AzureADandPersonalMicrosoftAccount"
93+
switch ($this->signInAudience) {
94+
case self::ACCOUNT_TYPE_SINGLETENANT:
95+
$this->authUrl = 'https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize';
96+
$this->tokenUrl = 'https://login.microsoftonline.com/organizations/oauth2/v2.0/token';
97+
break;
98+
case self::ACCOUNT_TYPE_PERSONAL:
99+
$this->authUrl = 'https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize';
100+
$this->tokenUrl = 'https://login.microsoftonline.com/consumers/oauth2/v2.0/token';
101+
break;
102+
case self::ACCOUNT_TYPE_MULTITENANT:
103+
case self::ACCOUNT_TYPE_MULTITENANTANDPERSONAL:
104+
default:
105+
$this->authUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
106+
$this->tokenUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
107+
}
108+
}
109+
110+
/**
111+
* {@inheritdoc}
112+
*/
113+
protected function initUserAttributes()
114+
{
115+
return $this->api('me', 'GET');
116+
}
117+
118+
/**
119+
* {@inheritdoc}
120+
*/
121+
public function applyAccessTokenToRequest($request, $accessToken)
122+
{
123+
$request->headers->set('Authorization', 'Bearer '.$accessToken->getToken());
124+
}
125+
126+
/**
127+
* {@inheritdoc}
128+
*/
129+
protected function defaultName()
130+
{
131+
return 'microsoft365';
132+
}
133+
134+
/**
135+
* {@inheritdoc}
136+
*/
137+
protected function defaultTitle()
138+
{
139+
return 'Microsoft 365';
140+
}
141+
142+
/**
143+
* {@inheritdoc}
144+
*/
145+
public function getEmail()
146+
{
147+
return $this->getUserAttributes()['mail'];
148+
}
149+
150+
/**
151+
* {@inheritdoc}
152+
*/
153+
public function getUsername()
154+
{
155+
return $this->getUserAttributes()['userPrincipalName'];
156+
}
157+
158+
}

0 commit comments

Comments
 (0)