azure-graph permission for users.get(principalID) - javascript

My code (Node.js):
const GraphkManagementClient = require('azure-graph');
client = new GraphkManagementClient(credentials, tenantId);
client.users.get(principalID);
The last line throws:
Authorization_RequestDenied: Insufficient privileges to complete the
operation.
I know how to grant privileges on Azure portal, but I don't know which one is the correct privilege of azure-graph for performing this operation. The list is so long:
(And this is just the beginning of the list)

Firstly you are assigning permissions for the wrong API as per screenshot in your question. It shows "Microsoft Graph" although your code will be using Azure AD Graph API.
In Azure portal navigate to Azure Active Directory > App registrations > Your app > Required permissions > Add (now in the Select an API select "Windows Azure Active Directory")
Now, if credentials used in your code are client id/app id and app secret, then you need to assign "Read directory data" under Application Permissions. For code like msRestAzure.loginWithServicePrincipalSecret
Otherwise, if you are prompting users to enter their credentials and doing something like interactive login, then assign "Read directory data" under Delegated Permissions. For code like msRestAzure.interactiveLogin()
Once you assign the relevant permissions, if any of those requires Admin consent, like it does in the above two cases I have shown, do the Admin consent. You can do it conveniently for the same tenant using "Grant Permissions" button at the end of the process.

Under your Microsoft Graph permissions for the App Registration in Azure Active Directory, grant 'Read Directory Data' permissions. This should be sufficient to make that call work. If that is too elevated, reference this for more information:
Microsoft Graph Permissions Reference

Related

ArcGIS JavaScript API: How to show company specific portal login screen when trying to access secure layer

I have written a webapp with the ArcGIS JavaScript API and all is working fine. Now I am trying to add secured layers to the web app and the app starts asking for credentials via a default login screen. I could use that, just entering username and password, but most users don't know their user name and password for ArcGIS.
The company has implemented SSO with ArcGIS so users don't have to fill in their credentials. Users typically go to the main company.maps.arcgis.com site and get to a company specific login screen where they have the option to click this SSO button.
My question; how can I make the JavaScript API show this company specific login page with SSO button instead of the default one?
I tried registering oauthInfo and serverInfo setting but without success.
Did anybody else ever built this?
The SSO sign in prompt should occur as long as you're using OAuthInfo and registering it with the IdentityManager. You'll have to make sure that you:
Add and register an application in the organization where
the data is coming from. The redirect URI should point to the server
that's hosting the application URL.
Get the Client ID from the registered application and add it to the appId in OAuthInfo along with the portalUrl property (which should be https://company.maps.arcgis.com)
Set the popup property to false.
Verify all the data is coming from the same organization. If it's not, then you may get another prompt since it's not registered with the IdentityManager.
Here's an example of what the OAuthInfo should look like:
const info = new OAuthInfo({
// Swap this ID out with registered application ID
appId: "APPID",
portalUrl: "https://company.maps.arcgis.com/",
flowType: "auto", // default that uses two-step flow
popup: false,
});
esriId.registerOAuthInfos([info]);

Active Directory access Azure Storage from browser

I want to use Azure Active Directory to allow users to read and write to Azure storage (specifically all Blobs and Tables) from a single-page web app.
I started like this:
import { InteractiveBrowserCredential } from '#azure/identity';
import { TableClient, TableServiceClient } from '#azure/data-tables';
const credentials = new InteractiveBrowserCredential({
clientId: myAuthConfig.clientId,
tenantId: myAuthConfig.tenantId,
});
const client = new TableServiceClient(
`https://${myAuthConfig.storageAccountName}.table.core.windows.net`,
credentials
);
client.listTables().byPage().next().then(console.log);
This works totally fine! I can see all the tables on the account. But then I wanted to list some of the data in on of the tables. So I did:
const client = new TableClient(
`https://${myAuthConfig.storageAccountName}.table.core.windows.net`,
'<table name>',
credentials
);
client.listEntities().byPage().next().then(console.log);
But this gives an error:
{
"odata.error": {
"code":"AuthorizationPermissionMismatch",
"message": {
"lang":"en-US",
"value":"This request is not authorized to perform this operation using this permission.\nRequestId:<uuid>\nTime:2021-10-28T18:04:00.0737419Z"
}
}
}
I'm very confused by this error. As far as I can tell I've done everything right. I followed every tutorial. I've set up active directory permissions for my app to use the storage API, my Microsoft account has permission to access the tables, OCRS is enabled, etc.
I'm not sure why I would have access to see a table but not see what's in it. I tried to use InteractiveBrowserCredential.authenticate to explicitly set scopes like this:
const scopes = ["User.Read"]
credentials.authenticate(scopes).then(console.log);
It works fine for User.Read but I couldn't figure out what scopes corresponded to Storage read/write access. If I added a scopy like "Microsoft.Storage" it told me that it didn't exist
Has anyone got an error like this before? What am I supposed to do here?
Thank you #gaurav mantri ,Posting your suggestion in comment as an answer.
From error it looks like your service principal does not have access permission to your table storage data. You should either grant permission using a RBAC role on the storage account resource (add to storage account contributors or readers) as below. Or use Storage Explorer to grant permission.
In your storage account please check, if you have Storage Table Data Contributer /Storage table data reader roles assigned as commented by #gaurav mantri
If not , you can add them
go into your storage account > IAM > Add role assignment, and add the special permissions
If roles are already assigned , the issue might be due to storage account being protected by firewall. Please try configure in Firewall and virtual networks of your storage account to add an existing virtual network or create a new vnet.If there is no issue you may allow access from all networks.
References:
Authorize access to tables using Active Directory - Azure Storage |
Microsoft Docs
Assign an Azure role for access to table data using powershell -
Azure Storage | Microsoft Docs

MailboxNotEnabledForRESTAPI When trying to update a user profile image in Azure AD from application

I have built an application that use Azure AD to authenticate users. In my web application, I have a profile page, in which the user can edit contact information and profile picture.
The permissions for the application have been approved by a global adminstration, and are as follows:
Delegated - Contacts.ReadWrite
Application - Contacts.ReadWrite
Delegated - Group.ReadWrite.All
Application - Group.ReadWrite.All
Delegated - User.Read
Delegated - User.ReadWrite
Delegated - User.ReadWrite.All
Application - User.ReadWrite.All
I'm currently having trouble updating the user profile picture in Azure AD (Which is displayed for the user on the website). I have tried to update the profile picture on behalf of the user, with a usertoken - But without any luck.
I then found this article, that describes how profile pictures effectively should be updated in Azure AD with the applications own token.
I have followed the "tutorial", and I can't see that I'm currently doing anything wrong, my code are as follows:
export const updateUserProfileImage = async (file) => {
const headers = new Headers();
const bearer = `Bearer ###TOKEN###`
headers.append("Authorization", bearer);
headers.append("Content-Type", "image/jpeg");
const options = {
method: "PUT",
headers: headers,
body: file
};
return fetch(`https://graph.microsoft.com/v1.0/users/USERLOGIN#MAIL.COM/photo/$value`, options)
}
When I post my request, I get the following response:
response:
error:
code: "MailboxNotEnabledForRESTAPI"
innerError:
client-request-id: "MYCLIENTID"
date: "2021-08-21T17:08:14"
request-id: "MYREQUESTID"
message: "The mailbox is either inactive, soft-deleted, or is hosted on-premise."
As far as I can understand, this behaviour is expected, i.e. from the article it says:
Note: When updating the user photo, this operation first attempts to
update the photo in Microsoft 365. If that fails (due to the user not
having a mailbox), this API will attempt to update the photo in Azure
Active Directory.
However, nothing happens after the error response - In other words, It seems as if Graph only attempts to update the photo in Microsoft 365, and then ends the operation with an error response.
It is possible to update profile photos via Graph API. However, v1.0 of the API only works with Exchange Online and not Azure AD, so the user account you are trying to update must be present in Exchange Online. This link tells more about the Profile Photo resource type.
If one tries to use the Graph API to update the photo of a user who does not have an Exchange Online mailbox it returns an error:
{"error":{"code":"MailboxNotEnabledForRESTAPI","message":"The mailbox is either inactive, soft-deleted, or is hosted on-premise.","innerError":{"date":"2021-07-19T12:49:54","request-id":"0a94b5f4-47ff-4f8c-8f24-b2f9622ba877","client-request-id":"0a94b5f4-47ff-4f8c-8f24-b2f9622ba877"}}}
To get a valid Office 365 mailbox, submit a request to your Exchange or Global administrator to migrate the mailbox account. Users who don't have administrator permissions can't migrate accounts. For information on how to migrate the mailbox account, see How to migrate mailbox data by using the Exchange Admin Center in Office 365
If a user has Exchange Online then do so via the Graph API or Set-UserPhoto.
Refer this document for more details.
And Also try with using user's work or school mailboxes and not personal mailboxes
Please refer this document for more details

Authenticate with Google as a specific User ID

I have set up Google Drive UI integration with my web app. When a user chooses to create a new file in Drive using my app, they are sent to
https://[mysite]?state={"folderId": "...", "action": "create", "userId":"..."}
I am signed in to multiple Google accounts (A and B) in my browser.
Account A opts to create a file, and is sent to my app with "userId": "[A's user id]" in the url.
However, with the gapi.auth2 JS library:
authInstance.signIn()
// Listen for sign in, and then:
authInstance.currentUser.get().getAuthResponse().access_token
Returns an access token for Account B.
This causes 404 errors when I try to create a file in folderId, which is only accessible to Account A.
How can my app authenticate with Google as the specific userId that opted to create a file?
The docs for Drive UI Integration do not seem to cover this issue, and the docs for Google Sign-In for Websites do not (as far as I can tell) provide a way to specify which account I want to sign in with (except through broad filters like "use a specific G Suite domain").
Update: The HTTP Google OAuth docs allow the client to specify a login_hint, which is an "email address or sub identifier" – it is not entirely clear what a "sub identifier" is. And, strangely, the Javascript API docs imply that login_hint is a response parameter, not something I can set.
Update 2 userId is an opaque Google-provoded integer value that I don't recognise. My app, Including the Drive upload, is fully client-side in JS and has no long-term data storage.

Login and pay with Amazon integration issue

So, I'm trying to integrate the Login and Pay with Amazon widget, and I'm encountering some problems.
So, I have my seller account all set up on
https://sellercentral.amazon.de/gp/
I have access to my API credentials, and I need to get a LWA client.
So, I have registered on
https://sellercentral.amazon.com/gp/homepage.htm
in order to create an application. I have set up the application, on web settings I have completed the required URL's, and got my client ID.
In the js for the Login and Pay with Amazon widget, I have replaced all the info needed: Client Id, merchant Id etc.
But when I try to make a test login, I receive the following error :
400 Bad Request Unknown client_id
The Pay With Amazon documentation is not very clear, and I can't seem to find anywhere a list with the error codes.
If anybody has an idea, let me know.
Thanks!
you should create your Login with Amazon application using https://sellercentral.amazon.de instead of the .com site. They are separate accounts.
It sounds like you're missing this piece of code:
window.onAmazonLoginReady = function() { amazon.Login.setClientId('CLIENT_ID'); }

Categories