Laravel OAuth 2.0 Authentication using Guzzle Client - php

I am developing an application like Postman Client in Laravel. For that, I am using Guzzle Client.
For OAuth 2.0 authentication, I have used the below link as reference,
Reference Link
I have tried the below code,
$token_storage = new FileTokenPersistence('/tmp/token.txt');
$baseurl="https://api.tradegecko.com/oauth/token";
$auth_code="";
$client_id="MYCLIENTID";
$client_secret="MYSECRET";
$redirect_uri="http://localhost:81/postman/public/request/instantadd";
if ($token_storage->hasToken() === false) {
$auth_url = 'https://api.tradegecko.com/oauth/authorize?'.http_build_query([
'client_id' => $client_id,
'redirect_uri' => $redirect_uri,
'response_type' => 'code',
'prompt' => 'select_account',
'scope' => '',
'access_type' => 'offline',
]);
echo "Go to the following link in your browser:\n\n";
echo " $auth_url\n\n";
// if(! defined('STDIN')) define('STDIN', fopen("php://stdin","r"));
echo "Enter verification code: ";
$auth_code = trim(fgets(STDIN, 1024));
}
$reauth_client = new \GuzzleHttp\Client(['verify' => 'E:\cacert.pem',
'base_uri' => $baseurl,
]);
$reauth_config = [
'code' => $auth_code,
'client_id' => $client_id,
'client_secret' => $client_secret,
'redirect_uri' => $redirect_uri,
];
$grant_type = new AuthorizationCode($reauth_client, $reauth_config);
$refresh_grant_type = new RefreshToken($reauth_client, $reauth_config);
$oauth = new OAuth2Middleware($grant_type, $refresh_grant_type);
$oauth->setTokenPersistence($token_storage);
$stack = HandlerStack::create();
$stack->push($oauth);
$client = new \GuzzleHttp\Client(['verify' => 'E:\cacert.pem',
'handler' => $stack,
'auth' => 'oauth',
]);
$response = $client->get($requesturl, $options);
$result=json_decode($response->getBody(),true);
I am getting an error in auth code retrieving. When I go to the authurl link, I am getting the token.
The error I am getting is:
"message": "Unable to request a new access token"
Also, I don't know what is the use of STDIN.....How can I put the auth code here?
Please help me.
Regards,Rekha

Related

microsoft graph:You cannot perform the requested operation, required scopes are missing in the token

I am calling one Microsoft graph API from my PHP application, API is https://graph.microsoft.com/beta/policies/identitySecurityDefaultsEnforcementPolicy
my code is like below
$graph = new Graph();
$graph->setAccessToken(session('my_token'));
try{
$response = $graph->createRequest("GET", "/policies/identitySecurityDefaultsEnforcementPolicy")->execute();
}
catch(Exception $e){
dd($e);
}
$arr = $response->getBody();
dd($arr);
but it always catches exception and displays the below error
Client error: `GET https://graph.microsoft.com/v1.0/policies/identitySecurityDefaultsEnforcementPolicy` resulted in a `403 Forbidden` response:
{"error":{"code":"AccessDenied","message":"You cannot perform the requested operation, required scopes are missing in the token.","innerError":{"date":"2022-11-23T06:47:39","request-id":"9a4573c7-fd72-44ae-8ac6-8e4589cf1497","client-request-id":"9a4573c7-fd72-44ae-8ac6-8e4589cf1497"}}}
all the other Microsoft graph APIs are working well
I have also given permission to Policy.Read.All and granted admin consent to the Microsoft app I am using here for auth.
Update: when I open Microsoft's online token parser https://jwt.ms/ and parsed my token, I see the roles like
"roles": [
"Mail.ReadWrite",
"User.ReadWrite.All",
"SecurityEvents.Read.All",
"Mail.ReadBasic.All",
"Group.Read.All",
"MailboxSettings.Read",
"Group.ReadWrite.All",
"SecurityEvents.ReadWrite.All",
"User.Invite.All",
"Directory.Read.All",
"User.Read.All",
"Domain.Read.All",
"GroupMember.Read.All",
"Mail.Read",
"User.Export.All",
"IdentityRiskyUser.Read.All",
"Mail.Send",
"User.ManageIdentities.All",
"MailboxSettings.ReadWrite",
"Organization.Read.All",
"GroupMember.ReadWrite.All",
"IdentityRiskEvent.Read.All",
"Mail.ReadBasic",
"Reports.Read.All"
]
but not the Policy.Read.All
Update: Getting auth token code is
$guzzle = new \GuzzleHttp\Client();
$url = 'https://login.microsoftonline.com/'.env("TANANT_ID").'/oauth2/token?api-version=beta';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => env("CLIENT_ID"),
'client_secret' => env("CLIENT_SECRET"),
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
// echo $token->access_token;
Session::put('my_token', $token->access_token);
When you're requesting the token, you need to supply a scope URL,
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#get-a-token
So as a basic example (this might not give the permission you need) but shows what your missing.
$guzzle = new \GuzzleHttp\Client();
$url = 'https://login.microsoftonline.com/'.env("TANANT_ID").'/oauth2/token?api-version=beta';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => env("CLIENT_ID"),
'client_secret' => env("CLIENT_SECRET"),
'resource' => 'https://graph.microsoft.com/',
'scope' => 'https://graph.microsoft.com/.default',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
// echo $token->access_token;
Session::put('my_token', $token->access_token);
specifically notice that i have added
'scope' => 'https://graph.microsoft.com/.default', to your form params
Looks like you don't have Policy.Read.All permission , could you please cross check permission through azure portal and provide the required permission and try again.
Thanks

GitLab oauth2 Laravel "{"message":"401 Unauthorized"}"

My gitLab controller. Links taken from the documentation. After submitting the form
returns an error "{"message":"401 Unauthorized"}" . Token is coming, but i want to
get username and email.
My gitLab controller
public function callback(Request $request)
{
$response = Http::withHeaders(['Accept' => 'application/json'])
->asForm()
->post('https://gitlab.com/oauth/token',[
'client_id' => config('oauth.gitlab.client_id'),
'client_secret' => config('oauth.gitlab.client_secret'),
'code' => $request->get('code'),
'grant_type' => 'authorization_code',
'redirect_uri' => config('oauth.gitlab.callback_uri'),
]);
$token = $response['access_token'];
$response = Http::withHeaders(['Authorization' => 'token ' . $token])
->get('https://gitlab.com/api/v4/user');
also link https://gitlab.com/api/v4/projects is work success
dd($response->body());
}
after checking I get an error 401. I don't understand why.
** My class GitlabServices**
public static function link(): string {
$params = [
'response_type' => 'code',
'client_id' => config('oauth.gitlab.client_id'),
'redirect_uri' => config('oauth.gitlab.callback_uri'),
'scope' => 'read_user openid'
];
return 'https://gitlab.com/oauth/authorize?' . http_build_query($params);
}
client_id, secret, redirect_uri store in .env
If you getting 401 in response. Check if the token privileges to request data.
Probably:
Token is not attached with request.
Token don't have privileges.
Adding 'token_type' to the request headers helped me
$token = $response->json('access_token');
$tokenType = $response->json('token_type');
$response = Http::withHeaders(['Authorization' => $tokenType . ' ' . $token])
->get('https://gitlab.com/api/v4/user');
The connection was successful and I received all the necessary information after making above mentioned changes.

How to Get Access Token and connect user without redirection from Microsoft Graph API using PHP

I tried this code but not get access token, but not working
I want to sync my outlook 365 calendar events with my system. My system is a background service, not an application, therefore i can't provide a login screen for the user to approve authorization.
I'm following this link in order to get an access token
Get access without a user
$guzzle = new \GuzzleHttp\Client();
$url='https://login.microsoftonline.com/'.config('azure.tenantId').'/oauth2/v2.0/token';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => config('azure.appId'),
'client_secret' => config('azure.appSecret'),
'scope' => config('azure.scopes'),
'username' => "youremail#domaine.com",
'password' => "password",
],
])->getBody()->getContents());
$accessToken = $token->access_token;
//Code to get data user form Microsoft Graph API
$graph = new Graph();
$graph->setAccessToken($token->access_token);
$user = $graph->createRequest('GET', '/me?$select=displayName,mail,mailboxSettings,userPrincipalName')
->setReturnType(Model\User::class)
->execute();
$tokenCache = new TokenCache();
$tokenCache->storeTokens($accessToken, $user);
The solution to Login direct without redirection
The documentation is clear, but I did not understand it well, but I finally found the solution after looking at the documentation step by step well
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc#authorization-request
try {
$guzzle = new \GuzzleHttp\Client();
$url = 'https://login.microsoftonline.com/'.config('azure.tenantId').'/oauth2/v2.0/token';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'grant_type' => 'password',
'client_id' => config('azure.appId'),
'client_secret' => config('azure.appSecret'),
'scope' => config('azure.scopes'),
'username' => "youremail#domaine.com",
'password' => "password",
],
])->getBody()->getContents());
$graph = new Graph();
$graph->setAccessToken($token->access_token);
$user = $graph->createRequest('GET', '/me?$select=displayName,mail,mailboxSettings,userPrincipalName')
->setReturnType(Model\User::class)
->execute();
$token = new \League\OAuth2\Client\Token\AccessToken(json_decode(json_encode($token), true));
$tokenCache = new TokenCache();
$tokenCache->storeTokens($token, $user);
return redirect('/');
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
return redirect('/')->with('error', 'Error requesting access token')->with('errorDetail', json_encode($e->getResponseBody()));
}

How to setup O365 made possible login with thephpleague/oauth2-client and working with msgraph-sdk-php?

I try to implement a php client, access a mailbox of a user with graph api. Because it's a background service, which should fetching specific mails attachment, it must run with grant type password.
So far, I got it really easy working make a login with thephpleague/oauth2-client and grant type client_credentials:
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => '...',
'clientSecret' => '...',
'redirectUri' => 'https://login.microsoftonline.com/common/oauth2/nativeclient',
'urlAuthorize' => null,
'urlAccessToken' => 'https://login.microsoftonline.com/.../oauth2/token?api-version=1.0',
'urlResourceOwnerDetails' => 'https://graph.microsoft.com/v1.0/me',
]);
$accessToken = $provider->getAccessToken('client_credentials');
Now I try it with grant type password, but it fails:
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => '...',
'clientSecret' => '...',
'redirectUri' => 'https://login.microsoftonline.com/common/oauth2/nativeclient',
'urlAuthorize' => null,
'urlAccessToken' => 'https://login.microsoftonline.com/.../oauth2/token?api-version=1.0',
'urlResourceOwnerDetails' => 'https://graph.microsoft.com/v1.0/me',
]);
$accessToken = $provider->getAccessToken('password', [
'username' => '...',
'password' => '...',
]);
Response I get: invalid_request. Google that error, I come to https://learn.microsoft.com/de-de/azure/active-directory/develop/v2-oauth2-auth-code-flow which tells me, I should fix my request.
Now... somehow it's hard, finding a) a ressource telling which urls are right and b) finding a tutorial, tell how I add right a app so I can get it working (maybe also a result, because the o365 layout changes fast...)
Does anyone have a idea, what the right parameters are and what I must do in the Azure Active Directory Admin Center so its working?
My goal is "only", access a users mailbox and get attachments from existing mails. I think, when I can authenticate successfully, all other things are easy (hope so).
Please refer to the official tutorial: Authenticate with the Microsoft Graph service.
To authenticate as an application you can use the Guzzle HTTP client, which comes preinstalled with this library, for example like this:
<?php
require __DIR__ . '/vendor/autoload.php';
$guzzle = new \GuzzleHttp\Client();
$tenantId = 'your_tenanet_id, e4c9ab4e-****-****-****-230ba2a757fb';
$clientId = 'your_app_id_registered_in_portal, dc175b96-****-****-****-ea03e56da5e7';
$clientSecret = 'app_key_generated_in_portal, /pGggH************************Zr732';
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token';
$user_token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'password',
'username' => 'your_user_id, jack#***.onmcirosoft.com',
'password' => 'your_password'
],
])->getBody()->getContents());
$user_accessToken = $user_token->access_token;
$graph = new Graph();
$graph->setAccessToken($user_accessToken );
$response = $graph->createRequest('Get','/me/messages')
->setReturnType(Model\Message::class)
->execute();
?>
Note that the resource should be https://graph.microsoft.com/

I need some solution with Google API Oauth

I'm trying to pull my list of Google contacts and display on a page the name and phone number.
I found an interesting post made by Lorna Jane and tried her code. I get a token returned, but every time I revisit the page, it asks me to authenticate again. With current code, no data array is pulled:
$id = 'secret.apps.googleusercontent.com';
$scope = 'https://www.google.com/m8/feeds/default/full/';
$uri = 'http://example.com/callback.php';
$params = array(
'response_type' => 'code',
'client_id' => $id,
'redirect_uri' => $uri,
'scope' => $scope
);
$query = 'https://accounts.google.com/o/oauth2/auth?' . http_build_query($params);
header('Location: ' . filter_var($query, FILTER_SANITIZE_URL));
if (isset($_GET['code']))
{
$code = $_GET['code'];
$token = 'https://accounts.google.com/o/oauth2/token';
$params = array(
'code' => $code,
'client_id' => $id,
'client_secret' => 'clientsecret',
'redirect_uri' => $uri,
'grant_type' => 'authorization_code'
);
$request = new HttpRequest($token, HttpRequest::METH_POST);
$request->setPostFields($params);
$request->send();
$responseObj = json_decode($request->getResponseBody());
var_dump($responseObj);
}
Please let me know what I'm missing. I prefer the pecl_http implementation, over the Google API library.

Categories