thenetworg/oauth2-azure
Composer 安装命令:
composer require thenetworg/oauth2-azure
包简介
Azure Active Directory OAuth 2.0 Client Provider for The PHP League OAuth2-Client
关键字:
README 文档
README
This package provides Azure Active Directory OAuth 2.0 support for the PHP League's OAuth 2.0 Client.
Table of Contents
- Installation
- Usage
- Making API Requests
- Resource Owner
- UPDATED - Microsoft Graph
- NEW - Protecting your API - experimental
- Azure Active Directory B2C - experimental
- Multipurpose refresh tokens - experimental
- Known users
- Contributing
- Credits
- Support
- License
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.certo your app in the Azure portal - Note the displayed thumbprint for the certificate (it looks like
B4A94A83092455AC4D3AC827F02B61646EAAC43D) - Put that thumbprint into the
clientCertificateThumbprintconstructor option - Put the contents of
private.keyinto theclientCertificatePrivateKeyconstructor option - You can omit the
clientSecretconstructor 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 followsodata.nextLinkuntil the end.$tenanttenant has to be provided since theodata.nextLinkdoesn'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
$refThe URL reference without the leading/, for examplemyOrganization/groups$bodyThe contents of the request, make has to be either string (so make sure to usejson_encodeto encode the request)s or stream (see Guzzle HTTP)$accessTokenThe access token object obtained by usinggetAccessTokenmethod$headersAbility 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 usergetFirstName()- Gets user's first namegetLastName()- Gets user's family name/surnamegetTenantId()- Gets id of tenant which the user is member ofgetUpn()- Gets user's User Principal Name, which can be also used as user's e-mail addressclaim($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
- Jan Hajek (TheNetw.org)
- Vittorio Bertocci (Microsoft)
- Thanks for the splendid support while implementing #16
- Martin Cetkovský (cetkovsky.eu]
- All Contributors
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.
thenetworg/oauth2-azure 适用场景与选型建议
thenetworg/oauth2-azure 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 10.6M 次下载、GitHub Stars 达 246, 最近一次更新时间为 2015 年 11 月 16 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「authorization」 「client」 「oauth」 「oauth2」 「SSO」 「azure」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 thenetworg/oauth2-azure 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 thenetworg/oauth2-azure 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 thenetworg/oauth2-azure 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
WeChat OAuth SDK
Ory-Hydra OAuth 2.0 Client Provider for The PHP League OAuth2-Client
Library for ORCID web services
A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.
Mock PSR-18 HTTP client
Asynchronous MQTT client built on React
统计信息
- 总下载量: 10.6M
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 253
- 点击次数: 25
- 依赖项目数: 46
- 推荐数: 11
其他信息
- 授权协议: MIT
- 更新时间: 2015-11-16