6
votes

Any user who logged into our system (IdentityServer as Auth) under a specific tenant should be able to create an event as an online meeting (MS Teams).

We followed Build ASP.NET Core MVC apps with Microsoft Graph and Create and enable an event as an online meeting to create an application that authenticates an AD user of an organization and allow him to create an event as an online meeting.

We are able to implement it successfully and was able to create the event as an online meeting.

But the exact scenario here is any user who is authenticated in our web application (not a AD user) should be able create a MS Teams meeting event and share it with other participants who should be able to join the meeting.

I am not sure how to achieve this.

Edit

Or at least how do I create onlineMeeting ? I tried with Client credentials provider as below

IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
    .Create("<<App_Id>>")
    .WithTenantId("<<Tenant_Id>>")
    .WithClientSecret("<<Client_Secret>>")
    .Build();


ClientCredentialProvider authenticationProvider = new ClientCredentialProvider(confidentialClientApplication);

GraphServiceClient graphClient = new GraphServiceClient(authenticationProvider);

var onlineMeeting = new OnlineMeeting
{
    StartDateTime = DateTimeOffset.Parse("2020-01-15T21:30:34.2444915+05:30"),
    EndDateTime = DateTimeOffset.Parse("2020-01-15T22:00:34.2464912+05:30"),
    Subject = "User Token Meeting"
};

var meeting = graphClient.Me.OnlineMeetings
.Request()
.AddAsync(onlineMeeting).Result;

but it was throwing

Code: Forbidden
Inner error:
    AdditionalData:
    request-id: <<some_id>>
    date: 2020-07-09T16:42:23
ClientRequestId: <<some_id>>
3
so you need all authenticated users to be able to create meeting, and not only AD once? is that correct?Maytham
Yes any user who is authenticated in my application should be able to create meeting.Gopi
@JamesMead My understanding about On-behalf-of is still they are passing the token obtained for the user. docs.microsoft.com/en-us/azure/active-directory/develop/… in this they have explained token A should be passed again along with Client id and Secret.Gopi
Right, my thinking was to have an A/D user that would act on behhalf of your other users [the ones authenticated by your application]. Don't know if it's feasible.Dan M

3 Answers

3
votes

I been working on your question in few days, I was going to mention some of the suggestions comes with the other answer. But in addition, the main challenge here, the system need to know who is authorized to do what.

So IMO The Best choice to solve this is creating a guest login in AzureAD, than you can use that to create a Team Events. Further more you can added an extra step after guest user logon, so that guest should enter his/her name and use it as reference.

1
votes

You will need to take these two steps.

  1. Get the right token
  2. Create an event (but change the url to https://graph.microsoft.com/v1.0/users/[email protected]/events)

The hard part is getting the right token, you have multiple options.

  1. Use the client credentials flow this will force an admin from every new tenant to authorize your application for their organization. You can then use the tenant from the user info to request a token for that tenant and use the user id to create the right url to post to.
  2. Make IdentityServer save the access token and allow you to access it. At coonfiguration level you have access to token callback and there you can also save the Azure AD access token. I think you can add it to a reference token, that way it isn't transmitted everytime but your web application is still able to access it.
  3. Use the on-behalf-of flow, this would require you to pass the Azure AD access token token retrieved from azure AD by the IdentityServer to be passed to your application.
  4. Just remove the identity server from the flow and have your web application logging straight with Azure AD. That way you'll have the right token available all the time.

Edit

After reading your editted question, what you want is a website where the user doesn't have to be an member of your Azure AD, just wants access to some new online meeting?

Best option is to created a shared mailbox, authorize an application (with Calendar.ReadWrite). Get a token with client credentials and call Create Event and then extract the meeting url from the event (that you'll get back when the posts completes succesfully.

1
votes

To create an online meeting for the "Client Credentials" flow, I used the following:

 var confidentialClientApplication = ConfidentialClientApplicationBuilder
     .Create("my-app-client-id")
     .WithTenantId("my-aad-tenant-id")
     .WithClientSecret("my-client-secret")
     .Build();
    
 var authProvider = new ClientCredentialProvider(confidentialClientApplication);
    
 var graphClient = new GraphServiceClient(authProvider);
    
 var meetingGuid = Guid.NewGuid();
 var createMeetingResponse = await graphClient.Users["my-aad-user-object-id"].OnlineMeetings
     .CreateOrGet(meetingGuid.ToString())
     .Request()
     .PostAsync();

The issue with your code is that referencing graphClient.Me causes the Graph requests to go to https://graph.microsoft.com/v1.0/me/onlineMeetings, which is not what you want in the "Client Credentials" flow. See this screenshot from the documentation found here: https://docs.microsoft.com/en-us/graph/api/onlinemeeting-createorget?view=graph-rest-1.0&tabs=csharp

enter image description here

I had to grant "application" permissions in Azure Portal to allow my app to access the online meetings API, and I had to create a client secret. I also had to follow this article to create a policy and grant it to specific users using Microsoft Teams PowerShell:

https://docs.microsoft.com/en-us/graph/cloud-communication-online-meeting-application-access-policy

For users not in your organization, you can invite them as a guest user to your tenant.

I had issues using the Microsoft Teams Powershell commands due to settings in Windows Remote Management, which I did something like this to work around:

https://lonesysadmin.net/2017/08/10/fix-winrm-client-issues/