public async Task <IActionResult> Subscribe( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("Subscribe function triggered!"); // Process the subscription request string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var request = JsonConvert.DeserializeObject <SubscriptionRequest>(requestBody); // Create a GraphServiceClient instance with the defined TokenCredential var graphClient = GraphUtility.GetGraphClient(); // Load the X509Certificate and add it to the subscription object var certificate = X509CertificateUtility.LoadCertificate(StoreName.My, StoreLocation.CurrentUser, Environment.GetEnvironmentVariable("CertificateThumbprint")); if (certificate == null) { log.LogError("Failed to load certificate!"); return(new StatusCodeResult(500)); } // Create a subscription var subscription = new Subscription { ChangeType = request.ChangeType, IncludeResourceData = true, NotificationUrl = $"{Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME")}/api/notify?code={Environment.GetEnvironmentVariable("NotifyFunctionKey")}", Resource = request.Resource, ExpirationDateTime = DateTime.UtcNow.AddMinutes(15), ClientState = request.ClientState, EncryptionCertificateId = !string.IsNullOrEmpty(certificate?.FriendlyName) ? certificate.FriendlyName : certificate?.Subject, }; // Associate the X509Certificate to the subscription object subscription.AddPublicEncryptionCertificate(certificate); try { Subscription subscriptionResult = await graphClient.Subscriptions.Request().AddAsync(subscription); string responseMessage = $"Subscription successfully registered with ID: {subscriptionResult.Id}"; return(new OkObjectResult(responseMessage)); } catch (Exception ex) { log.LogError(ex.Message); return(new StatusCodeResult(500)); } }
public async Task <IActionResult> Notify( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("Notify function triggered!"); // Graph Subscription validation logic, if needed string validationToken = req.Query["validationToken"]; if (!string.IsNullOrEmpty(validationToken)) { return(new OkObjectResult(validationToken)); } // Create a GraphServiceClient instance with the defined TokenCredential var graphClient = GraphUtility.GetGraphClient(); // Load the X509Certificate and add it to the subscription object var certificate = X509CertificateUtility.LoadCertificate(StoreName.My, StoreLocation.CurrentUser, Environment.GetEnvironmentVariable("CertificateThumbprint")); // Get the notification content string notificationContent = await new StreamReader(req.Body).ReadToEndAsync(); var collection = graphClient.HttpProvider.Serializer.DeserializeObject <ChangeNotificationCollection>(notificationContent); var acceptedTenantIds = new List <Guid>(); acceptedTenantIds.Add(new Guid(Environment.GetEnvironmentVariable("AZURE_TENANT_ID"))); var acceptedClientIds = new List <Guid>(); acceptedTenantIds.Add(new Guid(Environment.GetEnvironmentVariable("AZURE_CLIENT_ID"))); // Validate the tokens var areTokensValid = await collection.AreTokensValid(acceptedTenantIds, acceptedClientIds); foreach (var changeNotification in collection.Value) { // And decrypt the encryptedContent var actualNotificationItem = await changeNotification.EncryptedContent.DecryptAsync( (id, thumbprint) => Task.FromResult(certificate)); if (areTokensValid) { // Show the decrypted object content log.LogInformation($"Notification content: {actualNotificationItem}"); } } return(new OkResult()); }