I have created asp.net core web api application to connect to Microsoft Outlook calendar and add new event using graph api. I have created Microsoft office 365 E3 business account(trial). I have registered my application in active directory on Azure portal using same account. Set
my authentication class is
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using Microsoft.Graph;
namespace Helpers
{
public class MsalAuthenticationProvider : IAuthenticationProvider
{
private static MsalAuthenticationProvider _singleton;
private IPublicClientApplication _clientApplication;
private string[] _scopes;
private string _username;
private SecureString _password;
private string _userId;
private MsalAuthenticationProvider(IPublicClientApplication clientApplication, string[] scopes, string username, SecureString password)
{
_clientApplication = clientApplication;
_scopes = scopes;
_username = username;
_password = password;
_userId = null;
}
public static MsalAuthenticationProvider GetInstance(IPublicClientApplication clientApplication, string[] scopes, string username, SecureString password)
{
if (_singleton == null)
{
_singleton = new MsalAuthenticationProvider(clientApplication, scopes, username, password);
}
return _singleton;
}
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
var accessToken = await GetTokenAsync();
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
}
public async Task<string> GetTokenAsync()
{
if (!string.IsNullOrEmpty(_userId))
{
try
{
var account = await _clientApplication.GetAccountAsync(_userId);
if (account != null)
{
var silentResult = await _clientApplication.AcquireTokenSilent(_scopes, account).ExecuteAsync();
return silentResult.AccessToken;
}
}
catch (MsalUiRequiredException) { }
}
var result = await _clientApplication.AcquireTokenByUsernamePassword(_scopes, _username, _password).ExecuteAsync();
_userId = result.Account.HomeAccountId.Identifier;
return result.AccessToken;
}
}
}
and my controller is
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.Versioning;
using System.Security;
using System.Threading.Tasks;
using Helpers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Graph;
using Microsoft.Identity.Client;
using WebAPI_OneDrive.Models;
namespace WebAPI_OneDrive.Controllers
{
//[Route("api/[controller]")]
[ApiController]
public class OutlookController : ControllerBase
{
[HttpPost]
[Route("Outlook/CreateEvent")]
public async Task<string> CreateEventAsync(/*CredentialsModel model*/)
{
CredentialsModel model = new CredentialsModel();
model.applicationId = "9403804b-f9b6-4bb0-b8dd-2f40b4347ef1";
model.tenantId = "926349b9-42cb-46c0-bb34-970256de5c41";
model.userName = "[email protected]";
model.password = "p@ssw0rd";
var userName = model.userName;
var stringPassword = model.password;
var applicationId = model.applicationId;
var tenantId = model.tenantId;
var userPassword = new SecureString();
foreach (char c in stringPassword)
{
userPassword.AppendChar(c);
}
var config = LoadAppSettings(applicationId, tenantId);
var graphClient = GetAuthenticatedGraphClient(config, userName, userPassword);
//Create Event
var @event = new Event
{
Subject = "Let's go for lunch",
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = "Does noon work for you?"
},
Start = new DateTimeTimeZone
{
DateTime = "2022-07-19T12:00:00",
TimeZone = "Pacific Standard Time"
},
End = new DateTimeTimeZone
{
DateTime = "2022-07-19T14:00:00",
TimeZone = "Pacific Standard Time"
},
Location = new Location
{
DisplayName = "Harry's Bar"
},
Attendees = new List<Attendee>()
{
new Attendee
{
EmailAddress = new EmailAddress
{
Address = "[email protected]",
Name = "Samantha Booth"
},
Type = AttendeeType.Required
}
},
AllowNewTimeProposals = true,
TransactionId = "7E163156-7762-4BEB-A1C6-729EA81755A7"
};
var Event = await graphClient.Me.Calendar.Events
.Request()
.AddAsync(@event);
var EventId = Event.Id;
return EventId;
}
private static IConfigurationRoot LoadAppSettings(string applicationId, string tenantId)
{
try
{
var config = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false, true)
.Build();
config["applicationId"] = applicationId;
config["tenantId"] = tenantId;
if (string.IsNullOrEmpty(config["applicationId"]) ||
string.IsNullOrEmpty(config["tenantId"]))
{
return null;
}
return config;
}
catch (System.IO.FileNotFoundException)
{
return null;
}
}
private static IAuthenticationProvider CreateAuthorizationProvider(IConfigurationRoot config, string userName, SecureString userPassword)
{
var clientId = config["applicationId"];
var authority = $"https://login.microsoftonline.com/{config["tenantId"]}/v2.0";
List<string> scopes = new List<string>();
scopes.Add("User.Read");
scopes.Add("Calendars.Read");
scopes.Add("Calendars.Read.Shared");
scopes.Add("Calendars.ReadWrite");
scopes.Add("Calendars.Read.Shared");
//scopes.Add("Files.Read");
//scopes.Add("Files.ReadWrite");
//scopes.Add("Files.Read.All");
//scopes.Add("Files.ReadWrite.All");
//scopes.Add("Files.Read.Selected");
//scopes.Add("Files.ReadWrite.Selected");
//scopes.Add("Files.ReadWrite.AppFolder");
var cca = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(authority)
.Build();
return MsalAuthenticationProvider.GetInstance(cca, scopes.ToArray(), userName, userPassword);
}
private static GraphServiceClient GetAuthenticatedGraphClient(IConfigurationRoot config, string userName, SecureString userPassword)
{
var authenticationProvider = CreateAuthorizationProvider(config, userName, userPassword);
var graphClient = new GraphServiceClient(authenticationProvider);
return graphClient;
}
//Model
public class CredentialsModel
{
///credentials
public string password { get; set; }
public string userName { get; set; }
public string applicationId { get; set; }
public string tenantId { get; set; }
}
}
}
when I call Outlook/CreateEvent I am getting the following error
Please guide me how to fix this error, thanks in advance
CodePudding user response:
To resolve this issue, try to grant Application permission as below and and grant admin consent:
After adding application permission try to get a bearer token as below
Please check this reference List events - Microsoft Graph v1.0 | Microsoft Docs as per document Finally, I am getting list of calendar events successfully: