Failed to authenticate to Cloud IAP Backend from Cloud Tasks HTTP Request - google-iap

I'm trying to use Cloud Tasks HTTP Requests to reach a Kubernetes endpoint behind an HTTPS Load Balancer protected by Cloud IAP.
The endpoint works using any Gsuite company account as it should be but when the Cloud Task executes this is the Cloud Audit - Data Access log (only important parts displayed)
authenticationInfo: {
}
authorizationInfo: [
0: {
permission: "iap.webServiceVersions.accessViaIAP"
resource: "projects/<PROJECT_NUMBER>/iap_web/compute/services/<SERVICE_NUMBER>/versions/bs_0"
resourceAttributes: {
service: "iap.googleapis.com"
type: "iap.googleapis.com/WebServiceVersion"
}
}
]
status: {
code: 7
message: "PERMISSION_DENIED"
}
I'm using the compute-engine service account to create the task so I've granted this account the appropriate permissions:
When I create the task I add the appropriate OIDC service account email to the http request
'oidc_token': {'service_account_email': <PROJECT_NUMBER>-compute#developer.gserviceaccount.com}}
I also checked the Cloud Tasks HTTP Request on another endpoint and the Authentication Bearer token is present.
I really don't have any idea at this point on how to make it work.
Thanks for the help

I found the problem, the OIDC needed a specific audience to work with Cloud IAP.
The audience needed is the IAP ClientID that could be found in API & Services > Credentials under the section OAuth 2.0 client IDs with a name starting with IAP.
Just as an example here is the python code to add a task that can be granted access by the Cloud IAP.
# This is the important part, the audience filed is very important!
oidc_token = {'service_account_email': <PROJECT_NUMBER>-compute#developer.gserviceaccount.com, 'audience': <PROJECT_NUMBER>-<NUMBER_GENERATED_AUTOMATICALLY_BY_IAP>.apps.googleusercontent.com}
http_request = {'http_method': 'POST', 'url': url, 'body': json.dumps(payload).encode(), 'headers': headers, 'oidc_token': oidc_token}
task['schedule_time'] = timestamp
created_task = client.create_task(parent, {'http_request': http_request})

Related

Amazon sp-api Authorisation Workflow Issue

Following the SP-API developer guide, I created an app to be able to access SP-API. The app is in published state now and we tried the authorisation workflow as per the amazon guide steps:
https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/developer-guide/SellingPartnerApiDeveloperGuide.md#amazon-seller-central-partner-network-authorization-workflow
We are using the website authorisation workflow, the steps 1-3 work as per the guide,
Step 1. Initiate the authorization from the Amazon Seller Central Partner Network.
Step 2. The selling partner consents to authorize your application, we authorise the app from seller Central and start the process, this url loads
https://sellercentral.amazon.com/apps/authorize/consent?application_id=amzn1.sp.solution.6cf699bd-f89a-4afd-b64e-7d21351aaaaa
Step 3. The selling partner signs into your website, we are redirected to the website login and that is done, then we get the amazon state and partner id as part of the url:
https://dashboard.aaa.com/api/amzn/login?amazon_callback_uri=https%3A%2F%2Fsellercentral.amazon.com%2Fapps%2Fauthorize%2Fconfirm%2Famzn1.sp.solution.6cf699bd-f89a-4afd-b64e-7d21351aaaa&amazon_state=MTY0MzgzMjI2NzU2OADvv71PY8KzGA0Iaih1Nzjvv71bHNqRGO-_ve-_ve-_ve-_vRnvv70a77-9eTF577-9Ee-_vRDvv70W77-9FEnvv73vv71ueO-_vR7vv73vv70PYu-_vUJd77-9B--_vTxF77-977-9f--_vQ%3D%3D&selling_partner_id=A2079RJZNKAAAA
Step 4. Amazon sends you the authorization information - Then we are redirected back to Seller Central -
https://sellercentral.amazon.com/apps/authorize/confirm/amzn1.sp.solution.6cf699bd-f89a-4afd-b64e-7d21351aaaa?state=1d477f90edfa493a1d15&amazon_state=MTY0MzgzMjI2NzU2OADvv71PY8KzGA0Iaih1Nzjvv71bHNqRGO-_ve-_ve-_ve-_vRnvv70a77-9eTF577-9Ee-_vRDvv70W77-9FEnvv73vv71ueO-_vR7vv73vv70PYu-_vUJd77-9B--_vTxF77-977-9f--_vQ==&selling_partner_id=A2079RJZNKAAAA&redirect_uri=https://dashboard.aaa.com/api/amzn/redirect
We are getting the sp_oauth_code in the url and tried using that to request for refresh token via POSTMAN request but unable to proceed to request the token from amazon oauth service.
We are getting error 400 as response, this is request format from the postman code section:
var axios = require('axios');
var qs = require('qs');
var data = qs.stringify({
'grant_type': 'authorization_code',
'code': 'ANnGBdMPnXAlrMyfUdwaaa',
'client_id': 'amzn1.application-oa2-client.cf71c857f2fd4f2c968851619bdaaaaa',
'client_secret': 'bba375434456e9917fcd5539c4324cc0e3182cccb9f1694ce3c63bee4f1aaaaa',
'redirect_uri': 'https://dashboard.aaa.com/api/amzn/redirect'
});
var config = {
method: 'post',
url: 'https://api.amazon.com/auth/o2/token',
headers: { },
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
We are sending data as x-www-form-urlencoded as Json in the POST request.
Any pointers on what we could differently or check for any missing params - any inputs on what to look for would be greatly appreciated.
The SP-API documentation is a little vague on this as it says you should include the grant type, code, seller id and secret as query parameters which by definition means within the url.
You actually need to add them to the body of the POST request.
This is an interesting discussion which revealed the above to me: https://github.com/amzn/selling-partner-api-docs/issues/79
Hope it helps.

Issue authenticating to Auth0 via Swagger UI (.NET) with client credentials

I'm trying to authenticate to my Auth0 tenant via the Swagger UI (auto-generated by Swashbuckle.AspNetCore) using client credentials.
I'm getting the following error:
Auth ErrorError, error: access_denied, description: Non-global clients
are not allowed access to APIv1
Here's a screen shot:
Open API spec looks like this:
"securitySchemes": {
"auth0": {
"type": "oauth2",
"flows": {
"clientCredentials": {
"tokenUrl": "https://example.auth0.com/oauth/token"
},
"authorizationCode": {
"authorizationUrl": "https://example.auth0.com/authorize?audience=test",
"tokenUrl": "https://example.auth0.com/oauth/token",
"scopes": { }
}
}
}
}
I suspect this has something to do with the audience not being specified. I was having a similar issue with authorization code flow, but manged to get this working by appending the audience as a query-string param to the authorizationUrl (as shown above). Unfortunately the same trick doesn't work with client credential flow (i.e. attempting to append the audience to the tokenUrl). I need to support client credential flow, as one or more of the routes need to be locked down to M2M tokens only.
Interestingly, it works if I use the global client ID / secret (found under the advanced settings of the tenant), but I'm not sure if we should use this...
Anyone else ran into this issue and if so, any luck with finding a solution?

Regarding Microsoft Graph API integration in Angular - Spring Boot application

Graph API request for which you are seeing the problem
https://graph.microsoft.com/v1.0/me/messages
Graph API error message
{
'error': {
'code': 'InvalidAuthenticationToken',
'message': 'Access token validation failure. Invalid audience.',
'innerError': {
'request-id': '12e4940d-58af-4d64-98ab-4b3fe645afb8',
'date': '2020-05-05T13:57:38'
}
}
}
Description :
Implementing use case where user can extract emails in our application to download and consolidate attachments to central location using Microsoft graph.
Web application fronted is developed in angular and back-end is developed in spring boot REST API.
Integrating MSAL in angular to authenticate user and get valid tokens.
code configuration :
MsalModule.forRoot({
clientID: '83de5e6f-6a5b-48f4-8b64-5e8d6e70aa9d',
authority: 'https://login.microsoftonline.com/common/',
redirectUri: 'http://localhost:4200/TestLawyer/mail',
cacheLocation: 'localStorage',
// storeAuthStateInCookie: isIE, // set to true for IE 11
popUp: true,
consentScopes: ['user.read'],
unprotectedResources: ['https://www.microsoft.com/en-us/'],
protectedResourceMap: protectedResourceMap,
// logger: loggerCallback,
correlationId: '1234',
piiLoggingEnabled: true
})
I got the tokens in localstorage. In my solution i want to pass token to our spring boot rest server to extract emails using Microsoft Graph.
can you please help me on this like any tutorials or guidance to implement this use case.
The resource or scope of your token is incorrect.
You should set https://graph.microsoft.com/.default in the consentScopes.
You can decode your access token in https://jwt.io to see if the token includes the correct resource/scope.

Cant get simple Oauth wth vertx to work with google

Trying to create a web client that uses oauth to connect to multiple sso endopints, google mainly. This is on top of a spring boot project, I just keep getting the same error that no code is provided, but I'm not sure how i'm supposed to get a code without the access token first. Here is a simple version of what im trying to run I want localhost/8080 to redir to google to login and comeback to the same page or a different one doesn't matter
#RequestMapping("/google")
fun google(#RequestParam(value = "code") code: String?, model: Model): String {
val clientId = "asdf.apps.googleusercontent.com"
val secret = "1234"
var goog = GoogleAuth.create(Vertx.factory.vertx(), clientId, secret)
goog.authenticate(JsonObject().put("code", code), {
System.out.println(it)
})
return "test"
}
the error is always
"error": "invalid_request",
"error_description": "Missing required parameter: code"
}}
e```
but how can I provide a code first I need some sort of response from the server. I'm pretty familiar with restful oauth and must be missing something
You can't use the GoogleAuth like that. GoogleAuth provides the basic primitives to handle the OAuth2 protocol. As you're not using the vertx-web part you will need to setup a callback endpoint in your application (I guess it's the /google endpoint you listed) but now you miss the whole Oauth2 handshake. Your client (browser) should call Google, which calls your server to validate the code.
So what you're asking here is to re-implement the vert.x web Oauth2Handler using Spring Boot APIs.

Microsoft Graph API access token validation failure

I use this URL to get id_token:
https://login.microsoftonline.com/common/oauth2/authorize?
response_type=id_token%20code&
client_id=MY_CLIENT_GUID_ID_IN_HERE&
redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fopenid%2Freturn&nonce=alfaYYCTxBK8oypM&
state=6DnAi0%2FICAWaH14e
and this return result like this
http://localhost:3000/auth/openid/return?
code=AAA_code_in_here&
id_token=eyJ0eXAi_xxxx_yyyy_in_here&
state=6DnAi0%2FICAWaH14e&
session_state=xxxx_guid_xxxxx
and then i use the id_token to query Graph (use POST man)
i have see this post InvalidAuthenticationToken and CompactToken issues - Microsoft Graph using PHP Curl but make no sense.
OATH 2.0 requires multiple steps. The first request returns an OAUTH Code. The next step is converting that OATUH code into a Bearer Token. This is the step you are missing here.
I would also recommend using the v2 Endpoint which is a lot easier to work with (particularly with Graph). I wrote a v2 Endpoint Primer that walks through the process and may be helpful as well.
You can't use the token directly, there is one more step to exchange the code you get from the response url into token.
Here is my C# code (using Microsoft.IdentityModel.Clients.ActiveDirectory)
public static AuthenticationResult ExchangeCodeForToken(string InTenantName, string InUserObjId, string InRedirectUri, string InApplicationAzureClientID, string InApplicationAzureClientAppKey)
{
Check.Require(!string.IsNullOrEmpty(InTenantName), "InTenantName must be provided");
Check.Require(!string.IsNullOrEmpty(InUserObjId), "InUserObjId must be provided");
if (CanCompleteSignIn) //redirect from sign-in
{
var clientCredential = new ClientCredential(InApplicationAzureClientID, InApplicationAzureClientAppKey);
var authContext = new AuthenticationContext(Globals.GetLoginAuthority(InTenantName), (TokenCache)new ADALTokenCache(InUserObjId)); //Login Authority is https://login.microsoftonline.com/TenantName
return authContext.AcquireTokenByAuthorizationCode(VerificationCode, new Uri(InRedirectUri), clientCredential, Globals.AZURE_GRAPH_API_RESOURCE_ID); //RESOURCE_ID is "https://graph.microsoft.com/"
}
return null;
}
I had this issue today when I was playing with graph API, the problem in my case was how I was generating the token.
I used postman for generating the token wherein the Auth URL section I was adding the resource = client_id whereas it should be the graph URL. After making that change I was able to make the call via postman.
In order for the above to work, please make sure your application in Azure has delegated permissions to access the Graph API.
To receive the access token and use it for profile requests, you don't need anything from server-side, you can implement the oAuth2 just from the client side.
Use the following URL for login:
https://login.microsoftonline.com/common/oauth2/authorize?client_id=YOUR_CLIENT_ID&resource=https://graph.microsoft.com&response_type=token&redirect_uri=YOUR_REDIRECT_URI&scope=User.ReadBasic.All
After successful login, user will redirected to the page with access_token parameter. Then use the following AJAX call to fetch user info:
var token = login_window.location.href.split('access_token=').pop().split('&')[0];
$.ajax({
url: "https://graph.microsoft.com/v1.0/me",
type: "GET",
beforeSend: function(xhr){xhr.setRequestHeader('Authorization', 'Bearer '+token);},
success: function(data) {
alert('Hi '+data.displayName);
console.log(data);
}
});
Note that you may need to enable oauth2AllowImplicitFlow:true setting from your Azure Active Directory application manifest file.
Set "oauth2AllowImplicitFlow": false to "oauth2AllowImplicitFlow": true.
Lastly, ensure that your app has required permissions for Microsoft Graph which are sign in users and View users' basic profile
An updated answer to get access with new applications:
Register your app in the app registration portal.
Authorization request example:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&response_mode=query&scope=offline_access%20user.read%20mail.read&state=12345
Authorization response will look like this:
https://localhost/myapp/?code=M0ab92efe-b6fd-df08-87dc-2c6500a7f84d&state=12345
Get a token
POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=user.read%20mail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&client_secret=JqQX2PNo9bpM0uEihUPzyrh // NOTE: Only required for web apps
Use the access token to call Microsoft Graph
GET https://graph.microsoft.com/v1.0/me
Authorization: Bearer eyJ0eXAiO ... 0X2tnSQLEANnSPHY0gKcgw
Host: graph.microsoft.com
Source:
https://learn.microsoft.com/en-us/graph/auth-v2-user?context=graph/api/1.0
You can also get an access token without a user, see here:
https://learn.microsoft.com/en-us/graph/auth-v2-service

Resources