Unauthorized when requesting a token from Azure App Service - javascript

I'm creating a simple web app that needs to call an Azure Function.
I've registered 2 apps in my Azure AD: one for my single page react application and another for my Azure Function.
The app for my azure function has an API exposed on it and a scope configured called CallApi.
The app itself has authentication configured on it (easy auth), and the client id matches the API app registration within AAD:
The app for my SPA has permission to request this scope and this is granted by default for all users.
I am able to successfully log users into my SPA and get an access token. I'm doing this with the use of the #azure/msal-browser and #azure/msal-react npm libraries, specifically:
<MsalAuthenticationTemplate interactionType={InteractionType.Redirect} authenticationRequest={{scopes: ["User.Read", "api://<redacted>/CallApi"]}} >
However, the access token that is returned only has these scopes: ['openid', 'profile', 'User.Read', 'email'] and not api://<redacted>/CallApi. So when I try to exchange my access token for a token by sending a POST request to https://<app_name>.azurewebsites.net/.auth/login/aad it returns an unauthorized message.
How can I ensure that the CallApi scope is allow by my app?

So when I try to exchange my access token for a token by sending a POST request to https://<app_name>.azurewebsites.net/.auth/login/aad it returns an unauthorized message.
Please ensure that the URL is correct as it should be in the format of <app-url>/.auth/login/aad/callback and note that the parameters are in the body of the HTTP POST request.
However, the access token that is returned only has these scopes: ['openid', 'profile', 'User.Read', 'email']
openid
If an app performs sign-in by using OpenID Connect, then it must request the openid scope. That is to say, the openid scope displays on the work account consent page as the “Sign you in” permission.
email
The email scope can work with the openid scope. As it gives the app access to the user’s primary email address in the form of the email claim. Where, the email claim is included in a token only if an email address is associated with the user account, which isn’t always the case.
profile
The profile scope can also work with the openid scope. This gives the app access to a substantial amount of information about the user. The information that it has access includes, the user’s given name, surname, preferred username, and object ID.
In the Microsoft ecosystem there are some high-privilege permissions that can be set to admin-restricted. This include:
Firstly, read all user’s full profiles by using User.Read.All
Secondly, write data to an organization’s directory by using Directory.ReadWrite.All
Lastly, read all groups in an organization’s directory by using Groups.Read.All
Please refer this article for an example regarding the POST request regarding the Call API Scope.

Related

can we authenticate with response type as access token in MSAL JS

In Our application uses AAD for authenticating the corporate users within our organization only.
Is that possible to set the response type as access token instead of default id_token ? Here is my config.
// const msalConfig = {
// auth: {
// clientId: configuration.msal.clientId,
// tenantId:configuration.msal.tenantId,
// redirectUri: window.location.href
// },
// cache: {
// cacheLocation: 'sessionStorage',
// storeAuthStateInCookie: true
// }
// };
I get the error as but if i enable id_token in authentication under Azure App registrations authentication it works again.. but is that possible to get the authentication done just with access token enabled.
msal handleRedirectCallback ServerError: AADSTS700054: response_type 'id_token' is not enabled for
the application.
T
MSAL.JS is used implement browser level flows like
implicit flow.
Id token is required for implicit flow to validate that a user is
who they claim to be and get additional useful information about
Then for security purpose.
In implicit flow we need to first authorize with id token and then only we can request for access token.
Implicit flow is recommended only if the application has a single-page architecture (SPA), has no back-end components.
You are facing the error because implicit flow is not enabled.
To enable implicit flow please check Access tokens and ID tokens in your registered application as mentioned below
Do you mean you want to use Authorization Code Flow ? If so, you have to use MSAL v2.
EDIT: sorry, I misread the question.
You cannot directly ask for an access token with MSAL, you have to login first (id_token) and then acquire a token (access_token).
This is all explained in the docs.

Use Google Service Account with google API JavaScript Client

I wanted to know if it was possible possible to use a service account to request data from any google API but using this library: https://github.com/google/google-api-javascript-client
I managed to find out how to use the library with OAuth2.0 credential from google cloud console.
But my real need requires me to use a service account to fetch these data.
Here's the code I used to fetch data from OAuth2.0 credentials:
initClient() {
return gapi.client.init({
apiKey: this.GSC_API_KEY, // already defined in the application
client_id:
"xxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
scope:
"https://www.googleapis.com/auth/webmasters https://www.googleapis.com/auth/webmasters.readonly",
discoveryDocs: [
"https://www.googleapis.com/discovery/v1/apis/webmasters/v3/rest"
]
});
},
gapiList() {
this.initClient()
.then(() => {
// Executes an API request, and returns a Promise.
// The method name `webmasters.sites.list` comes from the API webmasters.
return gapi.client.webmasters.sites.list();
})
.then(
response => {
console.log(response.body);
},
err => {
console.error(err.details);
}
);
},
Here's the code that request the API:
gapi.load("client", this.gapiList);
It does return me good data.
But my final purpose requires me to use a service account.
The initClient function does need a client_id to load correctly. If I'm giving the client_id of the service account it does return me an error.
"Not a valid origin for the client: http://localhost:8080/ has not been whitelisted for client ID xxxxxxxxxxxxx. Please go to https://console.developers.google.com/ and whitelist this origin for your project's client ID.
The error message is telling me to whitelist the localhost (where I am currently working) but I don't find how to whitelist localhost for a service account.
Hope I gave enough informations.
Thank for any reply and help.
As the message tells, you need to allow localhost:8080 as an origin to call the API. To protect you and your users, Google restricts your OAuth 2.0 application to using Authorized Domains. If you have verified the domain with Google, you can use any Top Private Domain as an Authorized Domain.
After you add an Authorized Domain, you can use any of its subdomains or pages, and any other associated country codes. Add your Authorized Domains before you add your redirect or origin URIs, your homepage URL, your terms of service URL, or your privacy policy URL.
To accomplish this, follow these steps:
In the GCP Console, click APIs & Services and then OAuth consent screen. You might have to click Menu Menu first.
In the Application name field, enter G Suite Migrate and click Save.
In the left menu, click Credentials.
Click Create credentials and then OAuth client ID.
Select Web application.
In the Name field, enter a name for the OAuth web client.
In the Authorized JavaScript origins field, enter the URL that you’ll use to access the G Suite Migrate platform (for example,
http://localhost:5131).
Click Create.
Make a note of the client ID shown in the Client ID field. You’ll need it when you set up the G Suite Migrate platform. Tip: You can
also access the client ID from APIs & Serviceand thenCredentials.
Click OK.
Note: It might take some time for the authorization process to
complete.
Extra: If you want a service account to be able to call an API on a users behalf, you will also need to delegate domain-wide authority to the service account. This is explained in detail here.
You can not use service account with Google JavaScript client library.
You should use to Oauth2 authentication. If you have to use service account you need to use server sided language such like node.js or python etc.

Actions on Google authentication is not returning tokens

I'm integrating my smarthome services on the Actions on Google platform and I have some problems during the authentication process.
I have an Amazon Cognito user pool configured that I'm using for authentication, and apparently works fine, but I never receive the token on any request sent from Google to my back-end services.
The official documentation says the following:
"When you have authenticated a user, the user's third-party OAuth 2 access token is sent in the Authorization header when smart home intents are sent to your fulfillment."
But in fact, I don't receive that token.
{
"inputs": {
"0": {
"intent": "action.devices.SYNC"
}
},
"requestId": "7597788060327530693"
}
My account linking configuration:
https://i.stack.imgur.com/hLaVN.png
What you've posted is the request body. The headers should exist as a separate object in your request, which will be a key-value pair of metadata. One datum should be Authorization.

Facebook Javascript API not returning email on subdomain

I'm using facebook connect via their javsacript api to allow users to login to our site.
I'm just trying to return name and email.
All is fine on my dev box and our staging environment, but not on live. Live returns name, but not email...
dev and staging are on subdomains or our company domain. And live is on a subdomain of our clients domain.
If I examine the headers after the request to FB on live, a message comes back:
"message":"The field 'email' is only accessible on the User object after the user grants the 'email' permission."
The weird thing is that email is a permission given to apps by default.
My feeling is that the client top level domain might also have an FB app and something is clashing.
Any ideas?
thanks!
EDIT:
I am asking for email in the request, here's some code
$FB.api('/me', {fields: 'name,email'}, function(response) {
angular.element('.user-data-fields input[name=name]').val(response.name);
angular.element('.user-data-fields input[name=email]').val(response.email);
});
and here is the request to FB
https://graph.facebook.com/me?access_token=BIGOLDACCESSTOKENGOESHERE&callback=FB.__globalCallbacks.f33b1b77a8&debug=all&fields=name,email&method=get&pretty=0&sdk=joey
and the response from FB:
"message":"The field 'email' is only accessible on the User object after the user grants the 'email' permission."
thanks :)

Google Javascript API: What happen after access token expire?

I have a client-side web app (no backend) that uses Google Javascript API.
I have an issue regarding the access-token that I got after the login is successful.
From the callback, we can see that the access-token is set to expire in 1 hour.
expires_in: "3600"
Question is, how can I "get a new token"?
From the documentation, I'm under the impression that after the token is invalid, we have to (and I quote) perform a new re-authorization flow with immediate set to true to get an up-to-date access token.
Source:
https://developers.google.com/+/web/api/javascript
However, when I tried to call again the auth method:
gapi.auth.authorize(parameters, callback)
I got the token object, but there's no access-token inside.
{
client_id: "{my_client_id}.apps.googleusercontent.com"
cookie_policy: undefined
expires_at: "1370371466"
expires_in: "86400"
g_user_cookie_policy: undefined
issued_at: "1370285066"
response_type: "token"
scope: "https://www.googleapis.com/auth/plus.login https://gdata.youtube.com"
}
Am I missing something? How do we usually get a refreshed token after one expired?
On client side, access token is temporary. This is by default online access to user resources. In order to get access tokens again, you need to redirect user for permissions again.
In the OAuth protocol, your app requests authorization to access resources which are identified by scopes, and assuming the user is authenticated and approves, your app receives short-lived access tokens which let it access those resources, and (optionally or more precisely on server side) refresh tokens to allow long-term access.
for server side apps and for offline access of user resource you need to have refresh token Refer to: Google Analytics API Automated Login
Also read: https://developers.google.com/accounts/docs/OAuth2WebServer
https://developers.google.com/accounts/docs/OAuth2UserAgent

Categories