I am having difficulty get a refresh token. For some reason it seems that the Graph API is not recognizing my offline_access scope. Here is my PHP code:
$oauthClient = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => "id",
'clientSecret' => "secret",
'redirectUri' => "redirect",
'urlAuthorize' => "https://login.microsoftonline.com/xxxx/oauth2/v2.0/authorize",
'urlAccessToken' => "https://login.microsoftonline.com/xxxx/oauth2/v2.0/token",
'urlResourceOwnerDetails' => '',
'scopes' => 'MailboxSettings.ReadWrite offline_access'
]);
From my redirect script, I get a code but not a refresh token. Shouldn't I get both or am I not understanding how it works.
You were using OAuth 2.0 code grant flow.
In this flow, you will firstly make a request to the authorize endpoint. The authorize endpoint will return an authorization_code to you. Then you will make a POST request with the authorization_code to the token endpoint to get an access token and refresh token.
I checked the tutorial for OAuth 2.0 Client - Authorization Code Grant, the sample contains the logic for getting access token and refresh token. You can refer to the relevant code.
Related
I want to use the Microsoft Graph API on my application (which is actually on development).
I use fullcalendar js on my application (laravel 8) and when a user create an event on my application I want the same event create on his outlook calendar.
I want that the user connected on my application has only the right to access his outlook calendar (not all organization users calendar). In order to restrict this I understand that I have to use delegated autorizations and not applications autorizations.
First I would like to get an access token in order to use the API.
To do this I use oauth2 and guzzle :
$url = 'https://login.microsoftonline.com/' . env('MS_TENANT_ID'). '/oauth2/v2.0/token?api-version=1.0';
$tokenCall = Http::asForm()->post($url, [
'grant_type' => 'client_credentials',
'client_id' => env('MS_CLIENT_ID'),
'client_secret' => env('MS_CLIENT_SECRET'),
'scope' => 'https://graph.microsoft.com/.default',
'username' => 'xxx.xxx#xxx.com',
'password' => 'xxxxxxxx',
]);
$accessToken = json_decode($tokenCall->getBody()->getContents());
I obtain a token but when I inspect it with jwt.io, it appears that I haven't scopes in it (scp).
Do you know why it doesn't appears?
EDIT:
It appears that I use an application authentication and not a delegated authentication (for user).
So I change the 'grant_type' parameters for 'password' instead of 'client_credentials'.
But it throws me another error :
invalid_grant
AADSTS65001: The user or administrator has not consented to use the application with ID 'xxxxxxxxxxxxxxxxxxxxxxxx' named 'Graph PHP'. Send an interactive authorization request for this user and resource.
I read that in an delegated authentication I have to call the authorize point before the token point.
To do this I have to define a Redirect URI on my application on Azure. Unfortunately I made development on a local server (not localhost) which haven't SSL. Azure dosen't allow the Redirect URI to be on http except for localhost...
Is someone have already face this problem?
I'm using y0lk package to help me with OAuth1 and ETSY App, I managed to get the temporary credentials, but can't get my hand on Access tokens.
here's what I do :
$client = new Etsy([
'identifier' => '*********************',
'secret' => '*********',
'scope' => 'listings_r transactions_r',
'callback_uri' => 'http://*********.loc/slider/'
]);
$tempCred = $client->getTemporaryCredentials();
$tmpSecret = $tempCred->getSecret();
$tmpId = $tempCred->getIdentifier();
// Redirect to Etsy Autorisation login page
$redirect_url = $client->getAuthorizationUrl($tempCred);
$accessTokens = $client->getTokenCredentials($tempCred, $tmpId, $_GET['oauth_verifier']);
Ok, I don't know how to do, because to obtain the oauth verifier ( and do the $_GET['oauth_verifier']), I have to go by the login page, and then, to get the access token, I need my temp credentials, but to get then I 'll have to go again by new Etsy and this is why I always got the token revoked error..
I'm beginner, in PHP and with API, if someone see other mistakes in my way to do this, feel free to point them out for me :)
Thank you for your time.
Sorry but I am just learning about Microsoft Graph and I have spent the last 4 hours scouring Google to find my answer and my brain is going to explode so I have resorted to Stack.
I was using a previous method to authenticate a user to Azure AD but it has no more support and I want to switch over to Microsoft Graph. I am able to get the access token but that is as far as I get.
At this point all I want to do send the user to the Microsoft Login page so they can authenticate and be redirected back to my web app. I have read so much I don't know what else I can read. Is there anyone who can point me in the right direction to how to get this accomplished? also where in the world is the documentation for this?
$guzzle = new \GuzzleHttp\Client();
$tenantId = "***********************************";
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => '***********************************',
'client_secret' => '***********************************',
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
'redirect_uri' => 'https://www.example.com/here'
],
])->getBody()->getContents());
$accessToken = $token->access_token;
// Create a new Graph client.
$graph = new Graph();
$graph->setAccessToken($accessToken);
Comment moved to answer:
As I said in the comments, if you need to log in as a user and authenticate, please don't use a daemon-based client credential flow because there is no user interaction with this flow. You should use the authentication code flow, which requires you to log in to the user and obtain the authorization code, and then use the authorization code to redeem the access token.
Sample for your referenceļ¼
OAuth 2.0 PHP Sample Code.
Authentication and Authorization Using Auth0 in PHP.
Microsoft Graph Connect Sample for PHP.
I am using the tymondesigns/jwt-auth package for my app. I use customClaims to make my token.
Here is the code for login :
$token_data = [
'iss' => new Issuer('AreteHCM'),
'iat' => new IssuedAt(Carbon::now()) ,
'exp' => new Expiration(Carbon::now()->addDays(1)),
'nbf' => new NotBefore(Carbon::now()),
'sub' => new Subject('AreteHCMS'),
'jti' => new JwtId('AreteHCM'),
'user_data' => $user->user,
'menu_access' => $menu_access,
'login_time' => Carbon::now(),
];
$customClaims = JWTFactory::customClaims($token_data);
$payload = JWTFactory::make($customClaims);
$token = JWTAuth::encode($payload)->get();
For Logout, I invalidate the token, so the token can not be used anymore after the user logout.
JWTAuth::invalidate(JWTAuth::getToken());
I'm creating API (Backend) and the front end team using Angular. Eveythings went smooth, until the user logout and try to login again. After login, the user get the new account, but when he/she wants to access my middleware always rejects the token, it says that the token is blacklisted.
Here is my middleware :
$token = JWTAuth::getToken();
$data = JWTAuth::getPayload($token)->toArray();
It always shows error :
The token has been blacklisted in file C:\xampp\htdocs\aretehcm\vendor\tymon\jwt-auth\src\Manager.php on line 109
What I want to approach is :
User login get new token to access the API (every API request requires header auth Bearer token)
User logout will invalidate the token, so the token can not be used anymore to access the API
User login will get a new token so he/she can access the API
Is there any misconception from me about the JWT-API architecture ?
Thank you in advance for your replies and answers.
A quick google search pointed me towards this solution:
https://github.com/tymondesigns/jwt-auth/issues/983#issuecomment-275884324
I am having a hard time figuring out how to use the sign in with Apple. The documentation is terrible and failed responses leaves us clueless. The article of Aaron Parecki (https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple) does help a little, but I seem stuck now.
At first, I generate a login URL with /auth/authorize like so:
$_SESSION['state'] = bin2hex(openssl_random_pseudo_bytes(16));
return 'https://appleid.apple.com/auth/authorize?' . http_build_query([
'response_type' => 'code',
'response_mode' => 'form_post',
'client_id' => 'com.my.service.id',
'redirect_uri' => 'https://my.app/redirect'),
'state' => $_SESSION['state'],
'scope' => 'name email',
]);
After struggling with the domain verification and return URLs, this brings me to the Apple login page and returns to my redirect_uri after succesfull login. Then, I need to authorize the token which I execute using Guzzle:
$response = (new Client)->request('POST', 'https://appleid.apple.com/auth/token', [
RequestOptions::FORM_PARAMS => [
'grant_type' => 'authorization_code',
'code' => $_POST['code'],
'redirect_uri' => 'https://my.app/redirect',
'client_id' => 'com.my.service.id',
'client_secret' => $this->getClientSecret(),
],
RequestOptions::HEADERS => [
'Accept' => 'application/json'
]
]);
return json_decode($response, true);
The client secret is generated using Firebase php-jwt (https://github.com/firebase/php-jwt) and is valid through jwt.io:
$key = openssl_pkey_get_private('file://certificate.p8');
return JWT::encode([
'iss' => 'APPLETEAMID',
'iat' => time(),
'exp' => time() + 3600,
'aud' => 'https://appleid.apple.com',
'sub' => 'com.my.service.id',
], $key, 'ES256', 'certificate-id');
However, executing the token request to Apple returns a 400 error with the message 'invalid_client'. I cannot figure out if my client-id/secret is wrong or the code from the redirect is invalid. Can someone point me in the right direction?
EDIT:
Please note that I override the JWT class, allowing ES256 to be used. For more information, check this open pull request.
Based on what you said, and what Apple said in its documentation, I think you mistook Apple's Identity token with Client Secret.
Apple's Identity Token is a JWT token that uniquely identifies a user and is a layer of security "above" the existing OAuth 2.0 framework.
When you register/verify your client within an authorization server, based on the RFC 6749 - The OAuth 2.0 Authorization Framework, you most probably receive a secret from the authorisation server which is your client's secret (namely, a password for your server at com.my.service.id) to be used in EVERY request from obtaining tokens to using identities to retrieve resources. The suggested method to use this client_id/client_secret pair is HTTP Basic Authentication method, and using a POST parameter is discouraged.
The authorization server MUST support the HTTP Basic
authentication scheme for authenticating clients that were issued a
client password.
...
Including the client credentials in the request-body using the two
parameters is NOT RECOMMENDED and SHOULD be limited to clients unable
to directly utilize the HTTP Basic authentication scheme (or other
password-based HTTP authentication schemes). The parameters can only
be transmitted in the request-body and MUST NOT be included in the
request URI.
You will receive the user's Identity Token in a form of JWT token and you should provide THAT exactly and not tampered with, for this token is issued by Apple itself. You may, however, inspect the payload (see JWT Introduction at jwt.io) to know about the validity (iat + exp) of Identity Token. You should not generate an Identity Token unless you are coding for Apple's Authorization Team.
In the end, I cannot stress enough to read the OAuth spec thoroughly and remember that Identity Token is Apple's way of sending you a user's ID, but client_id and client_secret are something defined in OAuth spec.