Moving data from Google Big Query to Azure Data Lake Store using Azure Data Factory - google-bigquery

I have a scenario where I need to connect the Azure Data Factory (v2) in Google Big Query for to move data to my Azure Data Lake but I don't work.
When I create a Linked Service, I choose Big Query as Source, I put all informations about BigQuery, as project-name, type of connection, etc but when I click in Validade button a message is show for me: (for exemple)...
UserError: ERROR [28000] [Microsoft][BigQuery] (80) Authentication
failed: invalid_grant ERROR [28000] [Microsoft][BigQuery] (80)
Authentication failed: invalid_grant'Type=,Message=ERROR [28000]
[Microsoft][BigQuery] (80) Authentication failed: invalid_grant ERROR
[28000] [Microsoft][BigQuery] (80) Authentication failed:
invalid_grant,Source=,', activityId:
05ff5ce1-5262-4794-853c-c9e39b7f4b71
Any idea? Someone already tested this connector?
Tks.
Peeter Bonomo

The documentation for the ADF connector to BigQuery explains what the parameters mean, but it doesn't give any guidance on how to obtain the values for those parameters.
I spent a couple of days on this and finally got it to work. I used "User Authentication" because I wanted to use a cloud-based IR. The "Client Id" and "Client Secret" can be obtained by creating new credentials in the GCP Console. But to get the "Refresh Token", you have to do the OAuth2 dance with Google and intercept the token.
I put together a PowerShell script to do this for you and wrote up a post on GitHub that walks you through the process of authenticating ADF v2 to Google BigQuery:
https://github.com/AnalyticJeremy/ADF_BigQuery

This is the error you get for any access issues unfortunately. It's also the error you get when your refresh token has expired which it always does after 60 minutes. Which is incredibly curious....this like so many sets of instructions on OAuth2.0 authentication for ADF never mention all this work is to get a code that expires in 60 minutes. Without some method of refreshing it everytime you connect this is worthless. At least the following link mentions this error and you get it because the token has expired...its the only blog post (or Microsoft documentation) that bothers to mention this super big issue. https://medium.com/#varunck/data-transfer-from-google-bigquery-to-azure-blob-storage-using-azure-data-factory-adf-80659c078f83
Here's a different method which is what I will be attempting...it uses service account and IR https://www.youtube.com/watch?v=oRqRt7ya_DM

According to https://learn.microsoft.com/en-us/azure/data-factory/connector-google-bigquery, to connect to Google BigQuery via cloud IR, you need to provide the below information:
{
"name": "GoogleBigQueryLinkedService",
"properties": {
"type": "GoogleBigQuery",
"typeProperties": {
"project" : "<project ID>",
"additionalProjects" : "<additional project IDs>",
"requestGoogleDriveScope" : true,
"authenticationType" : "UserAuthentication",
"clientId": "<id of the application used to generate the refresh token>",
"clientSecret": {
"type": "SecureString",
"value":"<secret of the application used to generate the refresh token>"
},
"refreshToken": {
"type": "SecureString",
"value": "<refresh token>"
}
}
}
}
and that the user you use to grant permission to the application should have access to the project you want to query.
Thanks,
Eva

Related

Flutter Google Sign In Couchbase Authentication Code Flow

As we are migrating our app from Firebase to Couchbase, we also need to change the authentication part. We are using the google_sign_in package and would like to continue using it to have the native Google Sign In popup. Using the package we can get a serverAuthCode, which from my understanding we can then send to the _oidc_callback endpoint of Couchbase Sync Gateway. First I had to set disable_callback_state to true in the Sync Gateway configuration ("DisableCallbackState determines whether or not to maintain state between the /_oidc and /_oidc_callback endpoints."). However, when I now send the serverAuthCode to the _oidc_callback endpoint, I get the following error with status code 500:
body: {"error": "Internal Server Error", "reason": "Failed to exchange token: oauth2: cannot fetch token: 400 Bad Request\nResponse: {\n \"error\": \"invalid_grant\",\n \"error_description\": \"Bad Request\"\n}"}
I assume it is because the login was done using the package and not through the browser with a redirect to the app afterwards. Now I have no idea how to do this correctly though, that I sign in with the google_sign_in package and then use the code to get the tokens from the Sync Gateway. I can't find any helpful information for this problem.
I would be very happy if someone could help me, possibly in a call. Maybe this way something like this can be solved faster.

GCP text-to-Speech API auth issue

I was trying the above api in postman. Here is the request json:
{
"input":{
"text":"Flutter is awesome!"
},
"voice":{
"languageCode":"en-gb",
"name":"en-GB-Standard-A",
"ssmlGender":"FEMALE"
},
"audioConfig":{
"audioEncoding":"MP3"
}
}
for auth, i chose Bearer in postman auth and first executed the following command in my terminal to get the token:
gcloud auth application-default print-access-token
i pasted this token in auth header, and i received the following response :
{
"error": {
"code": 403,
"message": "Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the texttospeech.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/. If you are getting this error with curl or similar tools, you may need to specify 'X-Goog-User-Project' HTTP header for quota and billing purposes. For more information regarding 'X-Goog-User-Project' header, please check https://cloud.google.com/apis/docs/system-parameters.",
"status": "PERMISSION_DENIED",
"details": [
{
"#type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "SERVICE_DISABLED",
"domain": "googleapis.com",
"metadata": {
"consumer": "projects/12345678910",
"service": "texttospeech.googleapis.com"
}
}
]
}
}
I am very new to GCP in general and don't know how to navigate this issue. For additional context, i am trying to make a REST API call where i send the text and get a base64encoded string containig audio back. Any help is appreciated.
This is confusing/complex but the error is helpful:
Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the texttospeech.googleapis.com.
NOTE You can try this method using Google's APIs Explorer at this link
text.synthesize.
The issue is that gcloud is an OAuth2 application and tokens issued by gcloud either using gcloud auth print-[access|identity]-token and gcloud auth application-default print-access-token are issued against a Google-managed project (that Google provides for gcloud) and -- importantly -- not one of your own projects.
Google wants to provide gcloud for its users but does not want to provide arbitrary API access (for free) to its users. Hence the "not supported" part of the error.
The solution (as described) is that you should:
Use (or create) your own Google Project
Enable the Text-to-Speech service (API) in this project
Create a Service Account and key
gcloud auth activate-service-account providing the Service Account key
gcloud auth print-access-token to get an access token to invoke the API
See the following link for the steps:
https://cloud.google.com/text-to-speech/docs/libraries

Logic App query Azure Table using HTTP and Managed Identity authentication

I am trying to query Azure Table using the HTTP connector without success.
According to this document managed identity authentication is now possible for Azure Table:
https://learn.microsoft.com/en-us/azure/storage/tables/authorize-managed-identity
I have authorized the managed identity of the consumption logic app in the azure table using PowerShell as the documentation sugests.
https://learn.microsoft.com/en-us/azure/storage/tables/assign-azure-role-data-access?tabs=powershell
New-AzRoleAssignment -ObjectID xxxxxxxxxxxxxxxx `
-RoleDefinitionName "Storage Table Data Contributor" `
-Scope "/subscriptions/<subscription>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>/tableServices/default/tables/<table>"
Then in the logic app I've filled the request as documented in:
https://learn.microsoft.com/en-us/rest/api/storageservices/query-tables#request-headers
The run fails with forbidden missing authorization header.
"body": {
"odata.error": {
"code": "AuthenticationFailed",
"message": {
"lang": "en-US",
"value": "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:8d5dbe66-d002-0005-26e6-45da23000000\nTime:2022-04-01T16:35:57.2213453Z"
}
}
}
Any ideas?
So Basically with the setup bellow I was able to successfully query the Azure Table over HTTP
Headers:
Result:

MSGraph Multi-Factor Authentication "interaction_required"

I'm using the Microsoft Graph login endpoint: login.microsoftonline.com/[tenantId]/oauth2/token with a grant type of "password" to log users in:
{
"grant_type": "password",
"client_id": "xxx",
"client_secret": "xxx",
"scope": "openid",
"resource": "https://graph.microsoft.com",
"username": "username",
"password": "********",
}
When I post this with users that are not enrolled in multi-factor authentication on our AD I get back the expected results including an access_token and refresh_token
However on users that are enrolled I get back a HttpStatusCode.BadRequest with an error of "interaction_required"
According to documentation from Microsoft found here:
In this case, your app receives a 400 with an interaction_required
error during access token acquisition or a 403 with
insufficient_claims error when calling Microsoft Graph. In both cases,
the error response contains additional information that can be
presented to the authorize endpoint to challenge the user for
additional information (like multi-factor authentication or device
enrollment).
However I do not see any additional information in the results and can't find much information on next steps. The JSON I get back looks like this:
{
"error":"interaction_required",
"error_description":"AADSTS50079: Due to a configuration change made by your administrator, or because you moved to a new location, you must enroll in multi-factor authentication to access '00000003-0000-0000-c000-000000000000'.\r\nTrace ID: aee10c85-fd12-42ec-be6c-76d546500100\r\nCorrelation ID: 0ee3ebac-f702-4fbc-be76-fd6a291ad488\r\nTimestamp: 2021-09-09 17:45:24Z",
"error_codes":[50079],"timestamp":"2021-09-09 17:45:24Z",
"trace_id":"aee10c85-fd12-42ec-be6c-76d546500100",
"correlation_id":"0ee3ebac-f702-4fbc-be76-fd6a291ad488",
"error_uri":"https://login.microsoftonline.com/error?code=50079",
"suberror":"basic_action"
}
But I am getting back "interaction_required" and confirmed with our AD administrator that they are definitely enrolled. So I am at a bit of a loss for next steps to resolve this.
Cause :User is attempting a authentication method that requires Multi-factor authentication
Try to catch the error you get, and perform a new request according to steps for your flow scenarios by referring from this MS docs
Microsoft Graph has special considerations when building apps in
Conditional Access environments. Since Conditional Access policies are
assigned the specific datasets, Azure AD will enforce Conditional
Access policies based on the data behind Graph - rather than Graph
itself.
(or check below points)
Conditional access policies prevent non-interactive flows to work.
Possible solutions...
Use a interactive flow instead.
If you are using a interactive flow and still getting this error, please make sure openid is one of the scopes during the interactive sign-in. You might be getting the error after the interactive sign-in and trying to exchange the authorization code for a access token...
Example:
https://login.microsoftonline.com/contoso.onmicrosoft.com/oauth2/authorize?client_id=#...#
&response_type=code
&scope=openid groups.read.all
&nonce=1234
&redirect_uri=https://app.contoso.com
Notice "scope=openid groups.read.all" in the request above
Add the client application to the exception list of the Conditional Access Policy
Add the user to the exception list of the Conditional Access Policy
If you are not using conditional access policies and the user is directly enabled for MFA, then as a last thing, disable MFA for the user if solutions above do not work for you.
Or you can use certificate based authentication instead of MFA
References:
login-to-azure-web-application-fails-with-aadsts50079
SO thread

Google API analytics extraction permissions

Problem: cannot access Google Analytics View using API service (json credentials)
PHP Fatal error: Uncaught Google_Service_Exception: {
"error": {
"code": 403,
"message": "User does not have sufficient permissions for this profile.",
"errors": [
{
"message": "User does not have sufficient permissions for this profile.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
Detail: When creating a Google analytics account via "Google Account A [analytics]" and creating an API service "Google Account A [developer console - JSON credentials] I can access Analytics data using the API.
I've been given access (Edit, Collaborate, Read & Analyse, Manage Users ) to "Google Account B [Analytics]. Logged into a web browser I can access and see the GoogleAnalytics of Google Account B and have setup a 'Custom View' to access Custom dimensions.
(GA A [Analytics] -> GA A [Dev console]) --- Access OK
(GA B [Analtyics] -> GA A [Permission granted] -> GA A [Dev console]) --- Error
I am assuming if Google Account B created an API service and passed the credentials.json key file things would run smoothly. I want to use this as a last resort as the client will have no idea how to set this up.
I am looking for a reason (and solution to) why Google Account A can see the analytics view of (Google Account B) but the API service of Google Account A cannot access the view.
Original setup/testing: Google Analytics UserID API extraction
Thanks in advance
Answer: A service account in Google API (that is created when setting up the API project) is associated with a user.
This particular user must also be granted access by the owning Google Analytics account.
i.e. Service account xxxx.yyyy#googlepais.com that is created when
setting up a Google API service account.
Something sounds so simple but I was under the impression that since this account was created by a main Google account that already has access that these permissions were implicitly inherited... Not the case but kind of makes sense. And provides a lot more fine grained control.
Once this was granted the API extracted the correct information.