I'm trying to develop a web application that is connected to our AD Azure app which allows anyone with a code (specified in our own web application) to start a Teams meeting through the Ms Graph API.
The flow is simple as follows:
Use the host code to create the Ms Teams room
Store the created room information in our web app's database
Send users using a guest code to the correct Teams room
At first i tried using the beta Ms Graph API to use the 'application' permission type on which the host (in step 1) would create a meeting room in our AD Azure domain. This works however, refering the uuid of a user outside of our AD Azure domain isn't allowed or does not seem to work.
I then rewrote the web app to use the 'delegated' permission type. The user using the hostcode in step 1 is then redirected to Microsoft to log in, is returned to our web app with the correct auth tokens which we can use with Ms Graph to create the meeting rooms on behalf of the logged in user.
As far as i know, i configured the corresponding permissions for 'OnlineMeetings.ReadWrite' (or OnlineMeetings.ReadWrite.all, depending on the permission type). Admin consent has been done, i've even set the auth type to 'Accounts in any organizational directory (Any Azure AD directory - Multitenant)' but to no avail.
Both of these solutions seem to be quite limited to only our own AD Azure space/domain meaning we can't offer a web application that automatically creates a meeting room on behalf of a user and connects users to those same meetingroom.
Is there a way to allow the aforementioned?
For your requirement, I summarize two situations as below for your reference:
There are two tenants (tenant A and tenant B), your registered app is in tenant A and set as Accounts in any organizational directory (Any Azure AD directory - Multitenant).
1. If you want user in other AD to create a meeting room in tenant A, it can't be implemented.
2. If you want user in other AD to create a meeting room in current tenant(such as tenant B). You can request the token with id of tenant B in request token endpoint(like https://login.microsoftonline.com/{id of tenant B}/oauth2/v2.0/token. And in request body, you should use client id in tenant A of the registered app. We can just implement the steps by auth code flow and it will pop-up window to ask for login, you need to use admin account(of tenant B) to do the login at first time(to allow this operation).
Related
We have an web application that use Graph APIs, we granted it application permissions in app registration. Now we want to put the application to Microsoft App Source, is it possible to allow user of other tenants to use the permission of the app registration in our tenant? For example, one of the APIs is for creating calendar event to some users in this tenant, if use multi-tenant app registration, can people from other tenant create calendar event in their tenant successfully?
if use multi-tenant app registration, can people from other tenant
create calendar event in their tenant successfully?
Agree with #Tiny Wang, Yes we can do this , the multi-tenant Azure AD app should obtain authorization from other tenants, and when other tenants wish to create calendar events in their own tenant, they should specify their own tenant id when generating access tokens.
You can implement Get access without a user and use Application permission to access for create calender event .
Make sure that we need to get administrator consent for each tenant where we need to access.
For example if one app is registered in TenantA . And you want to access for create calender event in TenantB. Then we need to do admin consent as mentioned below
and Log in with an admin account of TenantB to do the admin consent for TenantB
To access the following url in a browser.
https://login.microsoftonline.com/{TenantB}/adminconsent
?client_id={ app registered in TenantA}
&state=12345
&redirect_uri={app registered in TenantA}
Then we will get an access token to create an calender event for the tenant B.
For more information please refer the below links:
SO THREAD| Error trying to access other tenant users calendars, using MS Graph API & Multi tenant support for Microsoft Graph API
Unable to authorize multiple users for a BOT within the same organization using Azure AD authentication
Following are the steps we tried.
1. Created an office 365 organization, so as to be the admin of the Azure AD
Registered the Azure AD app thru app registrations on Azure in the same Org, and then assigned the permissions to the app to read emails and calendar, by following the URL - https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp%2Cbot-msgraph-auth
Then created the web app bot under azure
Then under [OAuth Connection Settings] settings of the bot added the Azure AD app details, first added as Azure AD V1.0 with as per the recommendation in the URL of Microsoft
Used the standard template code of the project - BotAuthenticaionMSGraph from the Github sample code repository - https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore
In the sample code, we just need to edit the appsettings.json file to add the [ConnectionName, MicrosoftAppId, MicrosoftAppPassword]
Then published the local bot code to the app service of the web app bot on Azure
Tested the Bot Auth on the [Test in Web Chat] on Azure -- It works for my Azure AD
Then enabled the Directline Channel for bot and distributed bot to other users of the same organization
The issue is here - when the other user opens the bot, they can see the emails and calendar of the admin user who has already logged in initially. So when the other user logs off and logs in thru his AD credential, then only his emails and calendar data is available since then.
Issue - So, at a given point of time only one user's o365 data is visible globally on the bot chat, and not individual user's data who logs in for that session. The AD token is not per user session but instead its a universal token across for all the conversations.
When I use the Azure AD V2, I get the bad request while trying to login.
Please help. Thanks.
https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore
used the BotAuthenticaionMSGraph project
Expected is, every user should be able to log in individually, and only his data shud be visible on the bot conversation distinctively.
I have tested the sample code and it works fine for both Azure AD V1 and V2.
I followed Azure AD v2 to configure it. Don't forget to enter Mail.Read Mail.Send openid profile User.Read User.ReadBasic.All for Scopes. It's different from Azure AD V1. Otherwise, it will return 400 bad request while trying to login.
I didn't reproduce the first issue. Could you tell where the other user opens the bot? From "Test in Web Chat"?
Update
You need to be aware that your are dealing with two user identities:
The user’s identity in a channel.
The user’s identity in an identity provider that the bot is
interested in.
See Security considerations. When a bot asks user A in a channel to sign-in to an identity provider P, the sign-in process must assure that user A is the one that signs into P. If another user B is allowed to sign-in, then user A would have access to user B’s resource through the bot.
To enable the protection, you need to configure trusted Origins and tamper-proof user IDs.
You can refer to the sample code.
And this blog Using WebChat with Azure Bot Service’s Authentication provides more detailed infomration.
I have a client application which runs as daemon mode [no interfaces].
This daemon will speak to app created in Azure (single-tenant currently) to fetch users using O365 Graph API.
Authentication mechanism used is Auth2 certificate/thumbprint.
Permission to app is given directly by admin while creating app in azure itself.
Now i need to make this daemon (client) and app in azure as multi tenant.
Things i followed after reading some articles
Mark app as multi-tenant in azure
Point to /common in token url in client (which runs as daemon) https://login.microsoftonline.com/common/oauth2/token.
Questions:
After this i was able to get access token , but for any query i make i am getting error "The identity of the calling application could not be established".
Since there is no user intervention here , how do i give permission for tenant B app to access tenant A's data like users in my case ? Anything i can do in manifest file
If tenant B's app is accessing tenant's A data , should both app in azure be mutlitenant ?
Lot of articles explains how is the flow based on user login (user consent). But my client application runs as daemon. How do i give permission directly/mechanism in azure app for accessing other tenant's data ?
[Assume i am admin of both tenants and i have complete access to both tenant]
It isn't possible to use the common endpoint when using the client_credentials flow to log into the \OAuth2\token endpoint. This is because common is designed to identify the user's "home" directory and when they log in interactively they are redirected to sign into their home directory unless overwritten.
2 & 3. Tenant B doesn't get a registered application it only get an Enterprise Application. The linked Registered App would be the one is Tenant A, communication here isn't bi-directional. A has an Enterprise Application in A and an Enterprise Application in B. You set the permissions for all the Enterprise Applications using the Registered Application in A but an Admin/User -dependant on the permission type- will have to grant permissions in their respective tenant (A & B). When you log in as a user you utilise the Application Registration. In order to access B you will have to call the token endpoint containing B's tenant id.
To enable one application to be able to access multiple tenants you need to:
make the Application Multi-Tenanted. Make a note of the application's ApplicationId.
Using PowerShell log into the tenant you want to give the Application access to.
Use the Cmdlet New-AzureRmServicePrincipal -ApplicationId <ApplicationId> where is the one you noted earlier.
This will create a service principal in tenant B based on the application in Tenant A. The application in A when then be able to use the token endpoint for Tenant B to log in an access.
What I am trying to do is to automate the process of adding a new user to an Azure Active Directory of a tenant (the tenant is supplied as a parameter).
For this, I understood that I must use Azure AD B2B collaboration. The official sample for automating this process is provided by Microsoft at this link:
https://github.com/Azure/active-directory-dotnet-graphapi-b2bportal-web
So, using the Invitation API (which is available here: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/invitation_post), I programatically send an invitation mail to an email that I want to register.
The problem is that the user which will be registered with that email, will be registered within the tenant in which the application was configured.
For example I am using the tenant name X, to configure my application in the Azure Active Directory Portal. What I see is that I can only invite emails to register within my tenant named X.
What if I want to register an email within another tenant, tenant which I know beforehand?
Can the invitation Api specify in which tenant I want to register an email, without having the application registered in that tenant?
Because if I can't, I would have to register the application in all the tenants, and then apply logic in the code to link the Client ID and Client Secret to the correct tenant.
If I have understood your question correctly, you need a multi-tenant app.
When you get an access token for Microsoft Graph API, it will always target a specific tenant.
In order to get an access token which targets another tenant, you must:
Make your app multi-tenant: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-devhowto-multi-tenant-overview
An admin from the other tenant must perform a sign up, which asks them for consent to the permissions your app requires
This usually means a redirect to the login page with prompt=admin_consent in the query
After they consent, a service principal will be created in their tenant, and they are redirected back to your app as usual
Now you can get an access token targeting their tenant and use it to call Graph API
I've utilized the Partner Center REST API to provision tenants with orders/subscriptions. Now I want to start configuring the domains and users for the tenant I just created. My first step was to get a list of users using the Graph API https://msdn.microsoft.com/en-us/library/azure/ad/graph/api/users-operations as a test expecting to see the admin account. If I pass in the domain of the reseller account in the request URL, it shows me the reseller users. But when I put in the domain of the account I just provisioned, I get Invalid domain name in the request url. I'm using the resellers AD token to do this. I'm confused as it gives me the option to specify a domain, but I can only access my own.
What credentials am I supposed to be using here? I tried to use the user/pass that was generated for the admin account from the provision, but I get unauthorized_client when trying to get an AD token from the Graph API.
It is hard to directly address your issues here since they are a little broad, and I would need more specific details about the various tenants you are working with, how your app is provisioned, permissions your app has etc...
However I think there a few principals you can follow which may help you debug your issues.
All AAD Authentication happens within the context of a specific tenant. This means whenever you get an access token for a resource, the scope of that token is limited to the boundaries of the tenant.
To authenticate with a client application in the context of a tenant, you must have the app registered in the tenant you are trying to access (line of business application / single tenant) or you have to make the app multi-tenant, in which case your app should be able to function in the context of any tenant... if the right provisioning has occurred.
Every tenant where your app is trying to function must have a service principal for the application provisioned in the tenant. This service principal represents your application's identity in the context of that tenant, and acts as a place to store the permission your application has in the context of that tenant. Most normally, this service principal gets provisioned into a tenant after a user from that tenant has consented to use the app as a part of the login experience.
If you are trying to use user context (authorization code grant flow) to retrieve details about a tenant, you must ensure that that user is present in the directory you are trying to query. For example a user U can exist in their home tenant T1. If you try to query another tenant T2 using that user account, you will get any number of errors describing that the user account does not exist etc. You can remedy this by creating a guest account for U in T2, in which case there will be a brand new user object created in T2 which links to the original user object in T1. None the less, the user object should always be present in the tenant you are trying to query.
If you are trying to sign into an application with a user account that is in T1 and T2, you need to be sure to specify the tenant you want to actually get the token for. By default, if you use the common endpoint, you will get a token for the users home tenant. However, it is perfectly valid to get a token for the secondary tenant, as long as you specify that to our Token Service when making the request.
Finally the client application you use to make these requests needs to have the right permissions to the Graph API if you want to make specific calls to the Graph API. Every tenant needs to individually consent to the application in their tenant context in order to provision the correct permissions to their application.
With those principals in mind:
The error you are getting with "unauthorized_client" seems to be an issue with application provisioning in the secondary tenant. Please make sure to first login to the application with a user from the secondary tenant, and make sure that user has the correct permissions to consent to your app (a tenant admin is best here).
For the second issue with "Invalid domain name in the request url" please try using some hints here.
Specifically this:
By using the myOrganization alias. This alias is only available when using OAuth Authorization Code Grant type (3-legged) authentication; that is, when using a delegated permission scope. The alias is not case sensitive. It replaces the object ID or tenant domain in the URL. When the alias is used, Graph API derives the tenant from the claims presented in the token attached to the request. The following URL shows how to address the users resource collection of a tenant using this alias:
https://graph.windows.net/myorganization/users?api-version=1.6.
I hope this puts you on the correct path to resolve most of your issues.
There are issues with sandbox accounts and Azure. Access to the Azure Management Portal for the sandbox isn't straightforward and at this time does not work properly. I had to create a free Azure account with my hotmail account, then link AD from the new account to my sandbox AD to bypass the bug. When adding a new directory to the new Azure account, select "Use existing directory", sign out, then sign into the sandbox account you want to link it to. Then create your app from the new account.
After getting my app setup properly and new credentials, I had to enable pre-consent with the instructions listed at the end of: https://github.com/Microsoft/Partner-Center-Explorer
Lastly, I had to login to the Graph API with the customers ID, but with the resellers credentials.
The scenarios on the Partner Center SDK website include a section "Manage user accounts and assign licenses" under the "Manage customer accounts" section.
These samples include creating users and assigning licenses and a link to a console test app.
As an aside, a new version of the Partner Center SDK has just become available here. It was released on July 5th. While there is no official change history that I can find, I can see that it includes some new classes such as CustomerUser. You may find it easier to use that library rather than hitting the REST API (depending on how much work you've already done).