Google oauth2 returns no id_token - oauth-2.0

I seem to miss something with oauth2. I get the access_token but not id_token!
I use the following to gain a google access_token by passing a "code" granted to me from https://accounts.google.com/o/oauth2/auth
$oauth2token_url = "https://accounts.google.com/o/oauth2/token";
$clienttoken_post = array(
"code" => $code,
"client_id" => $client_id,
"client_secret" => $client_secret,
"redirect_uri" => $redirect_uri,
"grant_type" => "authorization_code"
);
$curl = curl_init($oauth2token_url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $clienttoken_post);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$json_response = curl_exec($curl);
curl_close($curl);
var_dump($json_response);
Everything seems to work but according to Google's documentation https://developers.google.com/accounts/docs/OAuth2Login#exchangecode I should be getting access_token, id_token, expires_in, token_type which I do except for the id_token
var_dump($json_response); shows the following:
string(126) "{ "access_token" : "ya29.AHES6ZSGlHVW9qA23xs8bHBP578Ef8S5cntJIcPT_SHWA", "token_type" : "Bearer", "expires_in" : 3598 }
What am I missing here?

At the token endpoint an id_token is issued only if certain scopes are present, the documentation should clarify that.
It is issued only if the email, profile or OpenID Connect scopes were used. An id_token does not make sense otherwise.

First, you need to add id_token for response_type.
Then you need to check scopes.
And don't forget that for implicit flow nonce param is required.
For more information and example you can check:
http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest

Related

AcquireTokenForClient does not return a refresh token?

We are not receiving the refresh_token when requesting the token despite the documentation says that always you request a token you will receive a refresh token.
Might be accidentally missing/misunderstanding something ?
This is a piece of the code we are using:
var app = ConfidentialClientApplicationBuilder.Create("...")
.WithAuthority(AzureCloudInstance.AzurePublic, "...")
.WithClientSecret(CLIENTSECRET)
.Build();
AuthenticationResult result = await app.AcquireTokenForClient(ewsScopes)
.ExecuteAsync();
And here is the reference to the documentation that we are basing our expectation on:
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-configurable-token-lifetimes#refresh-tokens
Refresh tokens
When a client acquires an access token to access a protected resource, the client also receives a refresh token.
You are using Client Credentials flow here in your code here to acquire the token.
See here for documentation - IConfidentialClientApplication.AcquireTokenForClient(IEnumerable) Method
AuthenticationResult result = await app.AcquireTokenForClient(ewsScopes)
.ExecuteAsync();
Read here about the Client Credentials flow in more detail, and specifically what a successful response looks like in this case, which is only expected to have an access_token and no refresh_token.
{
"token_type": "Bearer",
"expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}
A different flow, like Authorization Code flow (usually used by web apps) returns back an access_token as well as a refresh_token.
You can read more about that flow and a response in that case here - Authorization Code Flow
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
"token_type": "Bearer",
"expires_in": 3599,
"scope": "https%3A%2F%2Fgraph.microsoft.com%2Fmail.read",
"refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD...",
}

Access Token contains almost all information from Identity Token

The tokens below are returned upon initial token request with Azure AD B2C. access_token contains most information that id_token contains.
My questions are that:
1 Since access_token contains most information that id_token contains, what scenario can access_token be used in place of id_token? what scenario must id_token be used instead of access_token?
2 What are the rules regarding use of both access_token and id_token in general?
Result upon initial token request
{
"access_token": "access_token",
"token_type": "Bearer",
"expires_in": "3600",
"refresh_token": "refresh_token",
"id_token": "id_token"
}
Below is the decoded token for the respective token:
Please note that access_token contains most information from id_token, including user information.
access_token
{
"iss": "url",
"exp": 1550539339,
"nbf": 1550535739,
"aud": "audience ",
"idp": "LocalAccount",
"sub": "guid",
"name": "user#email.com",
"emails": [
"user#email.com"
],
"tfp": "B2C_1_ROPC_Auth",
"ver": "1.0",
"iat": 1550535739,
"azp": "guid"
}
id_token
{
"iss": "url",
"exp": 1550539339,
"nbf": 1550535739,
"aud": "audience ",
"idp": "LocalAccount",
"sub": "guid",
"name": "user#email.com",
"emails": [
"user#email.com"
],
"tfp": "B2C_1_ROPC_Auth",
"ver": "1.0",
"iat": 1550535739,
"auth_time": 1550535739,
"at_hash": "access_token hash"
}
Update
Further to question 1 above:
Since access_token contains most information that id_token contains, can access_token be used instead of id_token? That is, when id_token must be used instead of access_token?
I will take google as a example,
1) let say you want to implement social login where u mostly need fields like email, 'first_name', 'last_name'., these fields are mostly available in id_token. so id_token is perfect suitable for authentication.
2) later u need to fetch google contacts of the login user., In such scenarios u can't get contacts of the user in id_token. this is where access_token comes, though u won't have the contacts in access_token but all permission to fetch the contacts.
An ID token is intended for authentication. It is represented as a JSON Web Token (JWT) that contains claims about an authentication event including the identity information for a resource owner. The ID token is intended for a client application (a single-page app) and its aud (audience) claim contains the OAuth 2.0 client_id of the client application.
An access token is intended for access by clients to resources that are owned by a resource owner. It is represented as either a JWT (e.g. Azure AD B2C represents an access token as a JWT) or an opaque token. The access token is intended for a resource application (e.g. an API app) and its aud claim contains the OAuth 2.0 client_id of the resource application.

A value is required for property 'displayName' of resource 'Group'

Hello Everyone,
I am trying to fetch all the office 365 groups using MS Graph API by using PHP Curl.
Below is my code as,
$ch = curl_init('https://graph.microsoft.com/v1.0/groups');
curl_setopt_array($ch, array(
CURLOPT_HTTPHEADER => array('Authorization: Bearer '.$accessToken, 'Content-Type: application/json;'),
CURLOPT_RETURNTRANSFER =>true,
CURLOPT_VERBOSE => 1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => json_encode(array('securityEnabledOnly'=>true))
));
$out = curl_exec($ch);
curl_close($ch); print_r($out);
OUTPUT:
{
"error": {
"code": "Request_BadRequest",
"message": "A value is required for property 'displayName' of resource 'Group'.",
"innerError": {
"request-id": "0961dd91-37ec-48d6-99bc-47f9e4b1d989",
"date": "2018-03-08T08:31:09"
}}}
I am using the same access token for fetching details by other MS Graph API's which are working fine but in this case, I get this error. Also, my tenant is approved for all users via admin consent.
Please help me in this as now I've no clue how to proceed.
The root of my issue (calling List Users) was that I was using POST and not GET, I see in the documentation that List Groups is supposed to be a GET as well. Using POST results in "A value is required for property '_______' of resource"

Slack API Message formatting

I would like to pass such a message through slack chat post API which will follow this format:
*Attention* where Attention word will be printed as bold with two stars before and after. But as slack itself considering * for formatting a word bold so the before after stars are not printing.
My script
$ch = curl_init("https://slack.com/api/chat.postMessage");
$data = http_build_query([
"token" => "*******",
"channel" => '#notifications-test',
"text" => '*Attention* `#channel` - Please inform the client. 75% of monthly hours have been used.'
]);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
Please help
Use "mrkdwn": false property. That would turn off auto formatting in Slack.

Microsoft Account OpenID authentication token request returns id_token but not access_token

In the documentation at https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-code
... it states that a successful response to a token request looks like:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
"token_type": "Bearer",
"expires_in": 3599,
"scope": "https%3A%2F%2Fgraph.microsoft.com%2Fmail.read",
"refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD...",
}
After the first step of authentication completes, I receive a code on the redirect and use it to request a token.
However, I only receive this:
{
"token_type": "Bearer",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD...",
}
My scope is set to openid email profile.
Why do I not receive the access_token?
Access token will be returned only when resource specific scopes are requested, so that it can used to access the protected resource. Try including a scope like "https://graph.microsoft.com/mail.read" as indicated in sample present in the documentation link posted with the question.

Resources