Reputation: 129
I'm working on a calendar web application where I want to create a Teams meeting and add the meeting (the join-URL) to an appointment.
As not all of my users log in via Microsoft OAuth 2.0 login, I have to create the teams meeting on the server side (as application). I created an Azure app registration for my application and assigned it the API-permission "OnlineMeetings.ReadWrite.All" (Application). My application is using the client credentials authentication flow.
Now the actual problem:
I tried to create the onlineMeeting according to this Microsoft doc: Create onlineMeeting
The docs say, that I have to create an "application access policy" to create onlineMeetings as an application (Allow applications to access online meetings on behalf of a user)
So my question is: Is there really no straight forward way to create online meetings? In my opinion this is the most basic thing somebody wants to do when using Microsoft Graph in a Teams context. I can't believe that an admin has to take that much effort and connect oneself with a "Skype for business online"- PowerShell (Configure application access policy) and give the permission for every single user manually. I thought the Azure API permissions should exactly cover cases like that.
For testing purposes I tried the following, but only got the Microsoft.Graph.ServiceException "Code: General Message: User not found.". I think this is because my AuthenticationProvider is a ClientCredentialProvider and I am accessing an API for a user.
var client = new GraphServiceClient(azureService.ClientCredentialProvider);
var onlineMeeting = new OnlineMeeting()
{
StartDateTime = start,
EndDateTime = end,
Subject = subject
};
var test = await client.Me.OnlineMeetings
.Request()
.AddAsync(onlineMeeting);
Therefore, I also tried it this way (Microsoft.Graph.ServiceException: 'Code: BadRequest Message: An error has occurred.):
var meeting = await client.Communications.OnlineMeetings
.Request()
.AddAsync(onlineMeeting);
and that way (Microsoft.Graph.ServiceException: 'Code: BadRequest Message: This API is Not supported. createOrGet action is only supported for /me/onlineMeetings/createorGet):
var meeting = await client.Communications.OnlineMeetings
.CreateOrGet(new Guid().ToString(), null, end, participants, start, subject)
.PostAsync();
So is there any other API or possibility that would fulfill my requirements? Meanwhile, I am a little frustrated and would be really grateful for any hint.
Upvotes: 3
Views: 5215
Reputation: 16066
Adding that policy is necessary as the doc said, because application permission is not safe enough because the permission is very "big", while user permission is considered safe by microsoft.
Firstly, per my testing, I found that I can create the online meeting directly via an access token which has correct role (application OnlineMeetings.ReadWrite.All*), but I prefer to use createEvent instead, because this API has a much more clear description on creating online meeting (need application permission of Calendars.ReadWrite).
But we also need to note that even the action is operated by application, but we still need to set a user in the request because we need to set an organizer for the meeting, I set my user id here. I didn't run any power shell script here.
===============some sample code here===========
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
namespace ConsoleApp1
{
class Program
{
static async Task Main(string[] args)
{
IConfidentialClientApplication app;
app = ConfidentialClientApplicationBuilder.Create("client_id_here")
.WithClientSecret("client_secret_here")
.WithAuthority(new Uri("https://login.microsoftonline.com/your_tenant_name_here"))
.Build();
AuthenticationResult result = null;
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
result = await app.AcquireTokenForClient(scopes)
.ExecuteAsync();
string accesstoken = result.AccessToken;
Console.WriteLine(accesstoken);
Console.ReadLine();
//=======
//send http post request here
}
}
}
Upvotes: 6