Getting IDX10205 when accessing backend api from frontend - node.js

I'm trying to set up a frontend React app service and a backend Node app service, which both require authentication, according to this tutorial.
I've followed the steps except that I needed to set "loginParameters": ["response_type=code id_token", "scope=openid api://<backend app id>/user_impersonation"] instead of additionalLoginParams since my app uses auth v2.
When my frontend app calls my backend api I get the following error
{"code":401,"message":"IDX10205: Issuer validation failed. Issuer: '[PII is hidden]'. Did not match: validationParameters.ValidIssuer: '[PII is hidden]' or validationParameters.ValidIssuers: '[PII is hidden]'."}
I don't know how to debug this as the useful information in the response is hidded and I can't find a way to show it when using Node. I have inspected the token and the issuer is https://sts.windows.net/<tenant id>/, but I don't know what's expected or how to set ValidIssuer.
What I do for authentication code-wise is calling /.auth/me from frontend after login to receive an access token and this token is passed to the backend api in the header as Authentication: Bearer <access_token>. I'm expecting Azure to handle everything else according to the settings made in the linked tutorial. Is this correct?
How can I debug this issue?
EDIT
This is how the Expose an API page of backend app registration looks.
This is the data of my access token.

Your question has been resolved, post it as the answer to the end of the question.
As I said in the comments, you need to obtain the 2.0 version of the token. So you need to change the accessTokenAcceptedVersion attribute of the application manifest to: "accessTokenAcceptedVersion": 2.

Related

Unauthorised error from getProfile when using node-auth0

I am trying to migrate authentication via auth0 from a jvm based solution which uses auth0 rest api to a node based solution using node-auth0.
At present its a 2 step process:
Get token via POST /oauth/token
Get user profile via /userInfo
In the node application, I am constructing AuthenticationClient while providing clientId, clientSecret and domain as AuthenticationClientOptions and able to get the token successfully using passwordGrant but when I use the same authenticationClient object to call getProfile while providing the token obtained from passwordGrant, I get this error:
Request failed with status code 401
What’s confusing is that in Auth0 dashboard, this request is successful.
I am using node-auth0 SDK Version: 2.42.0 on Node 15.14.0
The token obtained via passwordGrant will be processed to respond for userInfo. Hence, the token must have in its audience claim <your-auth0-domain>/userInfo.

Setting additionalLoginParams with auth v2

I've followed this guide to configure access to my backend app, but I use Node backend and React frontend. However I'm unable to perform the step Configure App Service to return a usable access token. I get the error "Cannot execute the request for site x because the site is running on auth version v2.". To handle this I tried instead editing the sheet authsettingsV2, and I believe I found that the property properties.identityProviders.azureActiveDirectory.login.loginParameters in v2 equals properties.additionalLoginParams in v1 as editing this v2 property according to the tutorial shows the desired property in the v1 authsettings sheet.
However accessing my frontend app with this setting I get the error AADSTS901002: The 'resource' request parameter is not supported. before even being able to enter my credentials.
I've also tried without the additionalLoginParams setting completely, this gives me the error {"code":401,"message":"IDX10511: Signature validation failed. Keys tried: '[PII is hidden]'. \nkid: '[PII is hidden]'. \nExceptions caught:\n '[PII is hidden]'.\ntoken: '[PII is hidden]'."} on the API call, and upon inspecting my token, I find that the audience is the Microsoft Graph API. But I guess that is expected with this setup.
How can I proceed to enable access to my backend app? / How do I set the additionalLoginParams in auth version v2?
I am not sure if you have a correct access token. Please note that I am not talking about id token. Because from your response_type=code id_token, there should be only one id_token returned, but obviously the id_token cannot call your api, because what you need is an access token.
If you have not obtained a correct access token, then you should request an access token in the next step, refer to this link.
In addition, I must explain that all 401 errors are caused by api audiences. Therefore, make sure that your Application ID URI is set in the scope parameter.
When requesting an access token, you need to set the scope to: scope=openid api://{back-end api client id}/.default. Set response_type to: response_type=token.

What is the best way to call an authenticated HTTP Cloud Function from Node JS app deployed in GCP?

We have an authenticated HTTP cloud function (CF). The endpoint for this CF is public but because it is authenticated, it requires a valid identity token (id_token) to be added to the Authorization header.
We have another Node JS application that is deployed in the same Google Cloud. What we want is to call the CF from the Node application, for which we will be needing a valid id token.
The GCP documentation for authentication is too generic and does not have anything for such kind of scenario.
So what is the best way to achieve this?
Note
Like every google Kubernetes deployment, the node application has a service account attached to it which already has cloud function invoker access.
Follow Up
Before posting the question here I had already followed the same approach as #guillaume mentioned in his answer.
In my current code, I am hitting the metadata server from the Node JS application to get an id_token, and then I am sending the id_token in a header Authorization: 'Bearer [id_token]' to the CF HTTP request.
However, I am getting a 403 forbidden when I do that. I am not sure why??
I can verify the id_token fetched from the metadata server with the following endpoint.
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=[id_token]
It's a valid one.
And it has the following fields.
Decoding the id_token in https://jwt.io/ shows the same field in the payload.
{
"issued_to": "XXX",
"audience": "[CLOUD_FUNTION_URL]",
"user_id": "XXX",
"expires_in": 3570,
"issuer": "https://accounts.google.com",
"issued_at": 1610010647
}
There is no service account email field!
You have what you need in the documentation but I agree, it's not clear. It's named function-to-function authentication.
In fact, because the metadata server is deployed on each computes element on Google Cloud, you can reuse this solution everywhere (or almost everywhere! You can't generate an id_token on Cloud Build, I wrote an article and a workaround on this)
This article provides also a great workaround for local testing (because you don't have metadata server on your computer!)

Azure Functions returns "401 Unauthorized" only with Postman

I have some troubles trying to call an Azure Function (code) with Postman.
I have already set up the Authentication / Authorization and settings.
It's working with my browser (with login page).
But when I try to use Postman, I'm getting 401 :
"You do not have permission to view this directory or page."
I also tried to use the Postman built-in (see configuration) Oauth2 to login. I can successfully get the tokens (access and refresh). But it seems that my API request to functions are not working...
Here is the final API Call: postman screenshot
The aad tenant_id starts with 8d6, the application client_id starts with 226, and the app secret ends with Av2.
Is there anything wrong ... ? It looks like actually, Azure Functions handle only Cookies for the authentication, that's why it's working with the browser and not Postman. How can I make it works with the header Authorization / Bearer ?
Thanks for your help !
The way you got the access token is not correct. Just like #Marc said, in your Postman you are not specifying a resource or scope. The postman get new access token tool only has the scope parameter, so you should use the v2.0 endpoint to get the access token.
Auth URL:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
Access Token URL:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
Scope:
{clientId}/.default

Nodejs - ADAL package issue

I am using adal-node package in my Nodejs app for authenticating against Azure AD.
URL: https://www.npmjs.org/package/adal-node
I am using acquireTokenWithAuthorizationCode method to get the token and it works fine.
When my auth code expires, I want to refresh my token using the below.
authenticationContext.acquireTokenWithRefreshToken(_tokenData.refreshToken, authdata.clientId, authdata.resource, callback).
But when I run this code, its giving me the below error.
"Get Token request returned http error: 400 and server response: {"error":"invalid_request","error_description":"AADSTS90014: The request body must contain the following parameter: 'client_secret or client_assertion'
The method will not accept client secret as its argument, but still it complains that it needs a client secret.
Can you please help?
Thanks
Anil
Unfortunately, the library does not support your scenario right now. The function acquireTokenWithRefreshToken that you are using was intended for OAuth public clients that don't require a client secret, but your app is an OAuth confidential client which does.
I have filed the following issue in the GitHub repo to track the need to add a new method that would support your scenario.
https://github.com/AzureAD/azure-activedirectory-library-for-nodejs/issues/22

Resources