How do I get an access token from Google Analytics using a service account? - rest

I need to do a POST request to get the access token from Google Analytics using a service account.
I need to bypass manual authorisation in a browser, so I have used a service account for which I have all the details, private_key, client_id, etc
https://www.googleapis.com/oauth2/v4/token&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion={PRIVATEKEY}
If I do the above, I receive not found.
Can anyone help?
Cheers

The Server Side Authorization Embed API demo has an example of doing this. The example uses the Google APIs client library for Python, but, as #DalmTo mentions in their comment, you could look at what it's doing under the hood to replicate the requests.
Here's what the code that gets the access token looks like:
import json
from oauth2client.client import SignedJwtAssertionCredentials
# The scope for the OAuth2 request.
SCOPE = 'https://www.googleapis.com/auth/analytics.readonly'
# The location of the key file with the key data.
KEY_FILEPATH = 'path/to/json-key.json'
# Load the key file's private data.
with open(KEY_FILEPATH) as key_file:
_key_data = json.load(key_file)
# Construct a credentials objects from the key data and OAuth2 scope.
_credentials = SignedJwtAssertionCredentials(
_key_data['client_email'], _key_data['private_key'], SCOPE)
# Defines a method to get an access token from the credentials object.
# The access token is automatically refreshed if it has expired.
def get_access_token():
return _credentials.get_access_token().access_token

Related

Add a REST API as data source in powerBI with Basic auth

I am trying to add a REST API to my powerBI report as a data source. The API uses Basic authentication. However, I don't want to keep my token in an unencrypted form in the query editor.
Currently, I am able to make it work by using the following in Advanced Query Editor with Anonymous authentication:
let
token = "apiKey",
options = [Headers=[Authorization="Basic " & token]],
Source = Json.Document(Web.Contents("https://api-url/api/v1/application", options))
in
Source
However, I am trying to use a method, so that I can put my apiKey in the data source credentials, and eventually keep this value as private.
Either as basic auth
Or as web API key

AzureAd get groups info when not in token

I few days ago I configured my AzureAd to get Id_Tokens for my app also with groupIds claims within the token.
Everything works fine, but if I add more than 5 groups to an user it fails because azure add the "hasgroups": "true" claims because token is to big to add it in the URL so I have to perform another request.
The point is that I am not be able to perform the request to then obtaining the groups. The token ID_TOKEN I have received is the following:
for the backend and front end azureAD filter this token is perfect and works fine
Then as it it said in the official Microsoft azure docs I have to perform another request to https://graph.microsoft.com/v1.0/users/{userID}/getMemberObjects
As you can see the aud claim is the same as my app client ID:
I am trying to perform the request with postman because I need it and this is the result
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token validation failure. Invalid audience.",
"innerError": {
"date": "2020-07-08T13:56:50",
"request-id": "6b2f3374-33e4-4a1a-9709-b8111cd2bc66"
}
}
}
As you can see the aud is not invalid because is the same as client_id
What am I doing wrong>? I have spent a lot of time dealing with that and I can't find the solution.
I have also tried with POST request and BODY
UPDATE
I found the problem, the problem was that I was using an id_token instead of a access_token. But for me ot would be ususer to be able to extract such information only by using id_token.
I still have a horrible inconvenience, because if you can only use access token I will have to change half the application because is only the front end which have access token and in backend I have aspects that were using id_token with the group information contained and did not need the access token at all .Now front end should have to add access token in every request header to be captured in backend to run son filters and aspects that are executed and require such information
Is it possible to get the same info but with id_token instead?
Instead of Get request use Post request for below query
Post https://graph.microsoft.com/v1.0/users/{userID}/getMemberObjects
{
"securityEnabledOnly": true
}
Please refer to this document
If you want to try with Graph explorer here is the link

Retrieve email from token | #auth0/auth0-spa-js

I have been trying to upgrade to #auth0/auth0-spa-js from auth0-js, although I could not get my head around reading an email from a token which in turn was obtained from await useAuth0().getTokenSilently()
I use jwt.io to decrypt the token, and this is what I get in the payload:
{
"iss": "https://TENANT_NAME.auth0.com/",
"sub": "auth0|SOME_HASH",
"aud": [
"https://API_IDENTIFIER",
"https://TENANT_NAME.auth0.com/userinfo"
],
"iat": 1563699940,
"exp": 1563786340,
"azp": "SOME_OTHER_HASH",
"scope": "openid profile email"
}
When I was using auth0-js I could just add scope: "openid email" to new auth0.WebAuth({...}) and voilà – I had email and email_verified in the payload of the decrypted token.
I believe the 2 part series of tutorials were not able to answer my question, and retrieving the token from a hooked getTokenSilently() inside my Apollo configuration was also a challenge on its own. I like the redirect implementation for SPA, however. Please, can you suggest a proper way to include email and email_verified in the token's payload?
UPDATE
By reading this piece of documentation on api-tokens I understood the token I am getting from getTokenSilently() is called the access token. I have been using ID tokens in all of my requests' headers till this day, and that was probably a bad approach:
In the OIDC-conformant pipeline, ID Tokens should never be used as API tokens.
Also, the documentation says:
The token does not contain any information about the user except for the user ID (located in the sub claim).
In many cases, you may find it useful to retrieve additional user information. You can do this by calling the /userinfo API endpoint with the Access Token.
Which I did by following the shell example. I have sent the request with my access token and magically got an object containing the user's profile information from Auth0's Custom API.
We got close, what is an algorithm converting the "sub" into user profile residing inside Auth0's Custom API which I can implement for my backend written in ruby?
Yes, as you mention, ID tokens should not be used as API Tokens. They have a different usage (and you don't want your API Token to be too big, because you send it in each request's headers).
To get the user email, you can just fetch the UserProfile given in the ID Token. To achieve that, you just have to call getUser instead of getTokenSilently.
If you want more infos about the user, you have 2 ways to fetch user info:
You use the Auth0 Management API to fetch the user infos, based on the user id (in the sub claim of the ID Token) and using this API endpoint. In Ruby, you can just use a basic HTTP request.
You use a rule to always include specific fields in the ID Token. For example, you can include user_metadata and app_metadata in your ID Tokens. That way, you can use it without additional API call. To achieve that, you will need a specific Rule that will run when ID Tokens are generated (more general API doc).
An example rule that would add all user_metadata and app_metadata to the ID token would be:
function (user, context, callback) {
const namespace = 'your_url_namespace_just_for_cosmetic_but_required/';
context.idToken[namespace + 'user_metadata'] = user.user_metadata;
context.idToken[namespace + 'app_metadata'] = user.app_metadata;
callback(null, user, context);
}
And you will have the info in your ID Token for your frontend to use.
For the record, more rules examples on this hard-to-find page.

OAuth2 with SPA + REST API

Lets say we have SPA written in Angular 2 and have REST API using Spring Boot.
Both of them deployed in different servers. And now I have to protect this API via Facebook's OAuth2, but I don't know which grant type suits to my problem.
I don't want to be an auth server, I don't want facebook to be my resource server, instead my own REST API is supposed to be a resource server.
From FB I just want username or email or some identifier.
If I understood correctly I have to use implicit grant flow, because it's not a web application, correct me please, if I'm wrong.
Does "authorization code" grant also could be a choice ?
I really read almost all the threads related to oauth, spring security..
But I didn't find any info related to exactly SPA and REST API for separate servers.
Any link/resource related to above problem is appreciated.
Thanks in advance and sorry if I did something wrong, it's my very first post here.
You need to implement Implicit Grant flow https://oauth2.thephpleague.com/authorization-server/implicit-grant/
you need HTTPS for safety.
example:
OAuth Server: https://myoauthserver.com
restapi: https://myrestapi.com
client: https://myclient.com
send a get request to oauthserver "authorize" url with params
response_type = token (sometimes 'code')
redirect_uri = myclient.com or myclient.com/something (the one u assign while making an oauth client )
client id = dfuvhiurehvher (whatever id)
some providers require additional parameters like "scope".
when you send a request if everything works. you will be redirected to your client with the token in the url.
your request:
GET: https://myoauthserver.com/oauth/authorize?response_type=token&redirect_uri=https://myclient.com&client_id=yourClientIdHere
if successful you'll be redirected to
https://myclient.com?token=yourTokenValueIsHere
you can now use javascript to retrieve and store token value maybe to localStorage and attach it when sending requests to restapi (https://myrestapi.com)
heres an example request from auth0.com
$.ajax({
cache: false,
url: "http://localhost:7001/api/appointments",
headers: { "Authorization": "Bearer " + ATTACH_YOUR_TOKEN_VALUE_HERE }
});
for more details check this
https://auth0.com/docs/api-auth/tutorials/implicit-grant

magento REST API not accessible in iphone

When I try to access rest API using iPhone I have passed following parameter in URL and used both methods POST and GET but it displays Access Denied.
oauth_version="1.0",
oauth_signature_method="HMAC-SHA1",
oauth_nonce="B0dlzkfMWCAn0TJ",
oauth_timestamp="1366280813",
oauth_consumer_key="klkjylsiozbv6vfdsqtuheqo3kmqqzv2",
oauth_token="t9pefrwylmg7webyepsqepotlhzbytkp",
oauth_signature="NeOwbCLUPbIyF9ErnHoFQOl9%2Bwo%3D"
I have worked with REST Client plugin available for Firefox and Chrome, REST API is work well using REST Client plugin but not accessible in iPhone.
I am generating a random value for oauth_timestamp, oauth_signature and oauth_nonce then also REST API is displaying Access Denied.
Please provide suggestions.
//here final_sign is signature generated from following procedure.
$nonce = substr(md5(uniqid('nonce_', true)),0,16);
$temprealm="http://magentohost/api/rest/products";
$realm=urlencode($temprealm);
$oauth_version="1.0";
$oauth_signature_method="HMAC-SHA1";
$oauth_consumer_key="dfddfgdgdfgddf6qgygmyvw7e3";
$oauth_access_token="fdgdfgfdgdfg357gimpdnuejvcbtk51ni";
$oauth_method="GET";
$oauth_timestamp=time();
$algo="sha1";
$key="sb88hfdihyg25ipt1by559yzbj2m3861&s7uhaheu8nrx961oxg6uc3os4zgyc2tm"; //consumer secret & token secret //Both are used in generate signature
$data="oauth_consumer_key=".$oauth_consumer_key."&oauth_nonce=".$nonce."&oauth_signature_method=".$oauth_signature_method."&oauth_timestamp=".$oauth_timestamp."&oauth_token=".$oauth_access_token."&oauth_version=".$oauth_version;
$send_data=$oauth_method."&".$realm."&".urlencode($data);
$sign=hash_hmac($algo,$send_data,$key,1); // consumer key and token secrat used here
$fin_sign=base64_encode($sign);
echo $fin_sign;
From your question I understand that you use a random value for the signature and the nonce.
The latter would be fine, but a random signature would lead the receiver not to trust you as a legitimate client.
So, actually, you get the response you requested (;-)). But that does not solve your problem.
You have to generate a valid signature for the magento system.