From d59b49d057795c81e81eeccdb9aed0aa1e3faf0f Mon Sep 17 00:00:00 2001
From: SANTHOSH B <63607175+santhoshb-msft@users.noreply.github.com>
Date: Tue, 19 Mar 2024 12:07:16 -0700
Subject: [PATCH] Add logic to validate token on webhook notification (#671)
* add validate webhook filter
* added logic for validate jwt token
* add appconfig to validate token and db migration
* manually validating tenant and saas resource
---
.../WebHook/AzureWebhookController.cs | 51 +-
src/CustomerSite/Startup.cs | 6 +-
.../20240312055030_baseline751.Designer.cs | 1174 +++++++++++++++++
.../Migrations/20240312055030_baseline751.cs | 20 +
.../Migrations/Custom/BaselineV751_Seed.cs | 35 +
src/Services/Utilities/ValidateJwtToken.cs | 76 ++
6 files changed, 1357 insertions(+), 5 deletions(-)
create mode 100644 src/DataAccess/Migrations/20240312055030_baseline751.Designer.cs
create mode 100644 src/DataAccess/Migrations/20240312055030_baseline751.cs
create mode 100644 src/DataAccess/Migrations/Custom/BaselineV751_Seed.cs
create mode 100644 src/Services/Utilities/ValidateJwtToken.cs
diff --git a/src/CustomerSite/Controllers/WebHook/AzureWebhookController.cs b/src/CustomerSite/Controllers/WebHook/AzureWebhookController.cs
index 881bd397..21e05ef8 100644
--- a/src/CustomerSite/Controllers/WebHook/AzureWebhookController.cs
+++ b/src/CustomerSite/Controllers/WebHook/AzureWebhookController.cs
@@ -9,6 +9,7 @@
using Marketplace.SaaS.Accelerator.Services.Configurations;
using Marketplace.SaaS.Accelerator.Services.Exceptions;
using Marketplace.SaaS.Accelerator.Services.Services;
+using Marketplace.SaaS.Accelerator.Services.Utilities;
using Marketplace.SaaS.Accelerator.Services.WebHook;
using Microsoft.AspNetCore.Mvc;
@@ -63,6 +64,22 @@ public class AzureWebhookController : ControllerBase
///
private readonly SubscriptionService subscriptionService;
+ ///
+ /// The JWT token validation.
+ ///
+ private readonly ValidateJwtToken validateJwtToken;
+
+ ///
+ /// The ApplicationConfig Repository.
+ ///
+ private readonly IApplicationConfigRepository applicationConfigRepository;
+
+ ///
+ /// The ApplicationConfig service.
+ ///
+ private readonly ApplicationConfigService applicationConfigService;
+
+
///
/// Initializes a new instance of the class.
///
@@ -72,7 +89,16 @@ public class AzureWebhookController : ControllerBase
/// The plan repository.
/// The subscriptions repository.
/// The SaaSApiClientConfiguration from ENV
- public AzureWebhookController(IApplicationLogRepository applicationLogRepository, IWebhookProcessor webhookProcessor, ISubscriptionLogRepository subscriptionsLogRepository, IPlansRepository planRepository, ISubscriptionsRepository subscriptionsRepository, SaaSApiClientConfiguration configuration)
+ /// The validateJwtToken utility
+ /// The application config repository
+ public AzureWebhookController(IApplicationLogRepository applicationLogRepository,
+ IWebhookProcessor webhookProcessor,
+ ISubscriptionLogRepository subscriptionsLogRepository,
+ IPlansRepository planRepository,
+ ISubscriptionsRepository subscriptionsRepository,
+ SaaSApiClientConfiguration configuration,
+ ValidateJwtToken validateJwtToken,
+ IApplicationConfigRepository applicationConfigRepository)
{
this.applicationLogRepository = applicationLogRepository;
this.subscriptionsRepository = subscriptionsRepository;
@@ -82,6 +108,9 @@ public AzureWebhookController(IApplicationLogRepository applicationLogRepository
this.webhookProcessor = webhookProcessor;
this.applicationLogService = new ApplicationLogService(this.applicationLogRepository);
this.subscriptionService = new SubscriptionService(this.subscriptionsRepository, this.planRepository);
+ this.validateJwtToken = validateJwtToken;
+ this.applicationConfigRepository = applicationConfigRepository;
+ this.applicationConfigService = new ApplicationConfigService(this.applicationConfigRepository);
}
///
@@ -94,6 +123,24 @@ public async Task Post(WebhookPayload request)
{
await this.applicationLogService.AddApplicationLog("The azure Webhook Triggered.").ConfigureAwait(false);
+ var appConfigValueConversion = bool.TryParse(this.applicationConfigService.GetValueByName("ValidateWebhookJwtToken"), out bool appConfigValue);
+
+ if (appConfigValueConversion && appConfigValue)
+ {
+ try
+ {
+ await this.applicationLogService.AddApplicationLog("Validating the JWT token.").ConfigureAwait(false);
+ var token = this.HttpContext.Request.Headers["Authorization"].ToString().Split(' ')[1];
+ await validateJwtToken.ValidateTokenAsync(token);
+ }
+ catch (Exception e)
+ {
+ await this.applicationLogService.AddApplicationLog($"Jwt token validation failed with error: {e.Message}").ConfigureAwait(false);
+
+ return new UnauthorizedResult();
+ }
+ }
+
if (request != null)
{
var json = JsonSerializer.Serialize(request);
@@ -106,7 +153,7 @@ public async Task Post(WebhookPayload request)
catch (MarketplaceException ex)
{
await this.applicationLogService.AddApplicationLog(
- $"An error occurred while attempting to process a webhook notification: [{ex.Message}].")
+ $"A Marketplace exception occurred while attempting to process a webhook notification: [{ex.Message}].")
.ConfigureAwait(false);
return BadRequest();
}
diff --git a/src/CustomerSite/Startup.cs b/src/CustomerSite/Startup.cs
index c3af61b7..d1b8f6d0 100644
--- a/src/CustomerSite/Startup.cs
+++ b/src/CustomerSite/Startup.cs
@@ -105,8 +105,7 @@ public void ConfigureServices(IServiceCollection services)
services
.AddTransient()
.AddScoped()
- .AddScoped()
- ;
+ .AddScoped();
if (!Uri.TryCreate(config.FulFillmentAPIBaseURL, UriKind.Absolute, out var fulfillmentBaseApi))
{
@@ -115,7 +114,8 @@ public void ConfigureServices(IServiceCollection services)
services
.AddSingleton(new FulfillmentApiService(new MarketplaceSaaSClient(fulfillmentBaseApi, creds), config, new FulfillmentApiClientLogger()))
- .AddSingleton(config);
+ .AddSingleton(config)
+ .AddSingleton();
services
.AddDbContext(options => options.UseSqlServer(this.Configuration.GetConnectionString("DefaultConnection")));
diff --git a/src/DataAccess/Migrations/20240312055030_baseline751.Designer.cs b/src/DataAccess/Migrations/20240312055030_baseline751.Designer.cs
new file mode 100644
index 00000000..0f908dbf
--- /dev/null
+++ b/src/DataAccess/Migrations/20240312055030_baseline751.Designer.cs
@@ -0,0 +1,1174 @@
+//
+using System;
+using Marketplace.SaaS.Accelerator.DataAccess.Context;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Marketplace.SaaS.Accelerator.DataAccess.Migrations
+{
+ [DbContext(typeof(SaasKitContext))]
+ [Migration("20240312055030_baseline751")]
+ partial class baseline751
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.1")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.ApplicationConfiguration", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("ID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Description")
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("ApplicationConfiguration");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.ApplicationLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("ActionTime")
+ .HasColumnType("datetime");
+
+ b.Property("LogDetail")
+ .HasMaxLength(4000)
+ .IsUnicode(false)
+ .HasColumnType("varchar(4000)");
+
+ b.HasKey("Id");
+
+ b.ToTable("ApplicationLog");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.DatabaseVersionHistory", b =>
+ {
+ b.Property("ChangeLog")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreateBy")
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("ID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("VersionNumber")
+ .HasColumnType("decimal(6,2)");
+
+ b.ToTable("DatabaseVersionHistory");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.EmailTemplate", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("ID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Bcc")
+ .HasMaxLength(1000)
+ .IsUnicode(false)
+ .HasColumnType("varchar(1000)")
+ .HasColumnName("BCC");
+
+ b.Property("Cc")
+ .HasMaxLength(1000)
+ .IsUnicode(false)
+ .HasColumnType("varchar(1000)")
+ .HasColumnName("CC");
+
+ b.Property("Description")
+ .HasMaxLength(1000)
+ .IsUnicode(false)
+ .HasColumnType("varchar(1000)");
+
+ b.Property("InsertDate")
+ .HasColumnType("datetime");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("Status")
+ .HasMaxLength(1000)
+ .IsUnicode(false)
+ .HasColumnType("varchar(1000)");
+
+ b.Property("Subject")
+ .HasMaxLength(1000)
+ .IsUnicode(false)
+ .HasColumnType("varchar(1000)");
+
+ b.Property("TemplateBody")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.Property("ToRecipients")
+ .HasMaxLength(1000)
+ .IsUnicode(false)
+ .HasColumnType("varchar(1000)");
+
+ b.HasKey("Id");
+
+ b.ToTable("EmailTemplate");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Events", b =>
+ {
+ b.Property("EventsId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("EventsId"), 1L, 1);
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("EventsName")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.HasKey("EventsId");
+
+ b.ToTable("Events");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.KnownUsers", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("RoleId")
+ .HasColumnType("int");
+
+ b.Property("UserEmail")
+ .HasMaxLength(50)
+ .IsUnicode(false)
+ .HasColumnType("varchar(50)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("KnownUsers");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.MeteredAuditLogs", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("CreatedBy")
+ .HasColumnType("int");
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime");
+
+ b.Property("RequestJson")
+ .HasMaxLength(500)
+ .IsUnicode(false)
+ .HasColumnType("varchar(500)");
+
+ b.Property("ResponseJson")
+ .HasMaxLength(500)
+ .IsUnicode(false)
+ .HasColumnType("varchar(500)");
+
+ b.Property("RunBy")
+ .HasMaxLength(255)
+ .IsUnicode(false)
+ .HasColumnType("varchar(255)");
+
+ b.Property("StatusCode")
+ .HasMaxLength(100)
+ .IsUnicode(false)
+ .HasColumnType("varchar(100)");
+
+ b.Property("SubscriptionId")
+ .HasColumnType("int");
+
+ b.Property("SubscriptionUsageDate")
+ .HasColumnType("datetime");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SubscriptionId");
+
+ b.ToTable("MeteredAuditLogs");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.MeteredDimensions", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime");
+
+ b.Property("Description")
+ .HasMaxLength(250)
+ .IsUnicode(false)
+ .HasColumnType("varchar(250)");
+
+ b.Property("Dimension")
+ .HasMaxLength(150)
+ .IsUnicode(false)
+ .HasColumnType("varchar(150)");
+
+ b.Property("PlanId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PlanId");
+
+ b.ToTable("MeteredDimensions");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.MeteredPlanSchedulerManagement", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("DimensionId")
+ .IsRequired()
+ .HasColumnType("int");
+
+ b.Property("FrequencyId")
+ .IsRequired()
+ .HasColumnType("int");
+
+ b.Property("NextRunTime")
+ .HasColumnType("datetime2");
+
+ b.Property("PlanId")
+ .IsRequired()
+ .HasColumnType("int");
+
+ b.Property("Quantity")
+ .IsRequired()
+ .HasColumnType("float");
+
+ b.Property("SchedulerName")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("StartDate")
+ .IsRequired()
+ .HasColumnType("datetime2");
+
+ b.Property("SubscriptionId")
+ .IsRequired()
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DimensionId");
+
+ b.HasIndex("FrequencyId");
+
+ b.HasIndex("PlanId");
+
+ b.HasIndex("SubscriptionId");
+
+ b.ToTable("MeteredPlanSchedulerManagement");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.OfferAttributes", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("ID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("Description")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("DisplayName")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("DisplaySequence")
+ .HasColumnType("int");
+
+ b.Property("FromList")
+ .HasColumnType("bit");
+
+ b.Property("IsDelete")
+ .HasColumnType("bit");
+
+ b.Property("IsRequired")
+ .HasColumnType("bit");
+
+ b.Property("Isactive")
+ .HasColumnType("bit");
+
+ b.Property("Max")
+ .HasColumnType("int");
+
+ b.Property("Min")
+ .HasColumnType("int");
+
+ b.Property("OfferId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ParameterId")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("Type")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.Property("ValueTypeId")
+ .HasColumnType("int");
+
+ b.Property("ValuesList")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("OfferAttributes");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Offers", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("OfferGuid")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("OfferGUId");
+
+ b.Property("OfferId")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("OfferName")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("Offers");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.PlanAttributeMapping", b =>
+ {
+ b.Property("PlanAttributeId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("PlanAttributeId"), 1L, 1);
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("IsEnabled")
+ .HasColumnType("bit");
+
+ b.Property("OfferAttributeId")
+ .HasColumnType("int")
+ .HasColumnName("OfferAttributeID");
+
+ b.Property("PlanId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("PlanAttributeId")
+ .HasName("PK__PlanAttr__8B476A98C058FAF2");
+
+ b.ToTable("PlanAttributeMapping");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.PlanAttributeOutput", b =>
+ {
+ b.Property("RowNumber")
+ .HasColumnType("int");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("IsEnabled")
+ .HasColumnType("bit");
+
+ b.Property("OfferAttributeId")
+ .HasColumnType("int");
+
+ b.Property("PlanAttributeId")
+ .HasColumnType("int");
+
+ b.Property("PlanId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Type")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.HasKey("RowNumber")
+ .HasName("PK__PlanAttr__AAAC09D888FE3E40");
+
+ b.ToTable("PlanAttributeOutput");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.PlanEventsMapping", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("CopyToCustomer")
+ .HasColumnType("bit");
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("EventId")
+ .HasColumnType("int");
+
+ b.Property("FailureStateEmails")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("Isactive")
+ .HasColumnType("bit");
+
+ b.Property("PlanId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SuccessStateEmails")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("PlanEventsMapping");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.PlanEventsOutPut", b =>
+ {
+ b.Property("RowNumber")
+ .HasColumnType("int");
+
+ b.Property("CopyToCustomer")
+ .HasColumnType("bit");
+
+ b.Property("EventId")
+ .HasColumnType("int");
+
+ b.Property("EventsName")
+ .IsRequired()
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("FailureStateEmails")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.Property("Id")
+ .HasColumnType("int")
+ .HasColumnName("ID");
+
+ b.Property("Isactive")
+ .HasColumnType("bit");
+
+ b.Property("PlanId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SuccessStateEmails")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.HasKey("RowNumber")
+ .HasName("PK__PlanEven__AAAC09D8C9229532");
+
+ b.ToTable("PlanEventsOutPut");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Plans", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Description")
+ .HasMaxLength(500)
+ .IsUnicode(false)
+ .HasColumnType("varchar(500)");
+
+ b.Property("DisplayName")
+ .HasMaxLength(100)
+ .IsUnicode(false)
+ .HasColumnType("varchar(100)");
+
+ b.Property("IsPerUser")
+ .HasColumnType("bit");
+
+ b.Property("IsmeteringSupported")
+ .HasColumnType("bit");
+
+ b.Property("OfferId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("OfferID");
+
+ b.Property("PlanGuid")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("PlanGUID");
+
+ b.Property("PlanId")
+ .HasMaxLength(100)
+ .IsUnicode(false)
+ .HasColumnType("varchar(100)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Plans");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Roles", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .IsUnicode(false)
+ .HasColumnType("varchar(50)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Roles");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.SchedulerFrequency", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Frequency")
+ .IsRequired()
+ .HasMaxLength(50)
+ .IsUnicode(false)
+ .HasColumnType("varchar(50)");
+
+ b.HasKey("Id");
+
+ b.ToTable("SchedulerFrequency");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.SchedulerManagerView", b =>
+ {
+ b.Property("AMPSubscriptionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Dimension")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.Property("Frequency")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("NextRunTime")
+ .HasColumnType("datetime2");
+
+ b.Property("PlanId")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.Property("PurchaserEmail")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Quantity")
+ .HasColumnType("float");
+
+ b.Property("SchedulerName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("StartDate")
+ .HasColumnType("datetime2");
+
+ b.Property("SubscriptionName")
+ .HasColumnType("nvarchar(max)");
+
+ b.ToView("SchedulerManagerView");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.SubscriptionAttributeValues", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("ID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("OfferId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("OfferID");
+
+ b.Property("PlanAttributeId")
+ .HasColumnType("int");
+
+ b.Property("PlanId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("PlanID");
+
+ b.Property("SubscriptionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.Property("Value")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.HasKey("Id");
+
+ b.ToTable("SubscriptionAttributeValues");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.SubscriptionAuditLogs", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Attribute")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("varchar(20)");
+
+ b.Property("CreateBy")
+ .HasColumnType("int");
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("NewValue")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.Property("OldValue")
+ .HasMaxLength(50)
+ .IsUnicode(false)
+ .HasColumnType("varchar(50)");
+
+ b.Property("SubscriptionId")
+ .HasColumnType("int")
+ .HasColumnName("SubscriptionID");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SubscriptionId");
+
+ b.ToTable("SubscriptionAuditLogs");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.SubscriptionEmailOutput", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Name")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("Value")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.ToTable("SubscriptionEmailOutput");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.SubscriptionParametersOutput", b =>
+ {
+ b.Property("RowNumber")
+ .HasColumnType("int");
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("DisplaySequence")
+ .HasColumnType("int");
+
+ b.Property("FromList")
+ .HasColumnType("bit");
+
+ b.Property("Htmltype")
+ .IsRequired()
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)")
+ .HasColumnName("HTMLType");
+
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("IsEnabled")
+ .HasColumnType("bit");
+
+ b.Property("IsRequired")
+ .HasColumnType("bit");
+
+ b.Property("Max")
+ .HasColumnType("int");
+
+ b.Property("Min")
+ .HasColumnType("int");
+
+ b.Property("OfferAttributeId")
+ .HasColumnType("int")
+ .HasColumnName("OfferAttributeID");
+
+ b.Property("OfferId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("PlanAttributeId")
+ .HasColumnType("int");
+
+ b.Property("PlanId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SubscriptionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.Property("Value")
+ .IsRequired()
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.Property("ValueType")
+ .IsRequired()
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("ValuesList")
+ .IsRequired()
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.HasKey("RowNumber")
+ .HasName("PK__Subscrip__AAAC09D8BA727059");
+
+ b.ToTable("SubscriptionParametersOutput");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Subscriptions", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("AmpOfferId")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("AmpplanId")
+ .HasMaxLength(100)
+ .IsUnicode(false)
+ .HasColumnType("varchar(100)")
+ .HasColumnName("AMPPlanId");
+
+ b.Property("Ampquantity")
+ .HasColumnType("int")
+ .HasColumnName("AMPQuantity");
+
+ b.Property("AmpsubscriptionId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("AMPSubscriptionId")
+ .HasDefaultValueSql("(newid())");
+
+ b.Property("CreateBy")
+ .HasColumnType("int");
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("EndDate")
+ .HasColumnType("datetime2");
+
+ b.Property("IsActive")
+ .HasColumnType("bit");
+
+ b.Property("ModifyDate")
+ .HasColumnType("datetime");
+
+ b.Property("Name")
+ .HasMaxLength(100)
+ .IsUnicode(false)
+ .HasColumnType("varchar(100)");
+
+ b.Property("PurchaserEmail")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.Property("PurchaserTenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("StartDate")
+ .HasColumnType("datetime2");
+
+ b.Property("SubscriptionStatus")
+ .HasMaxLength(50)
+ .IsUnicode(false)
+ .HasColumnType("varchar(50)");
+
+ b.Property("Term")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Subscriptions");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Users", b =>
+ {
+ b.Property("UserId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("UserId"), 1L, 1);
+
+ b.Property("CreatedDate")
+ .HasColumnType("datetime");
+
+ b.Property("EmailAddress")
+ .HasMaxLength(100)
+ .IsUnicode(false)
+ .HasColumnType("varchar(100)");
+
+ b.Property("FullName")
+ .HasMaxLength(200)
+ .IsUnicode(false)
+ .HasColumnType("varchar(200)");
+
+ b.HasKey("UserId");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.ValueTypes", b =>
+ {
+ b.Property("ValueTypeId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("ValueTypeId"), 1L, 1);
+
+ b.Property("CreateDate")
+ .HasColumnType("datetime");
+
+ b.Property("Htmltype")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)")
+ .HasColumnName("HTMLType");
+
+ b.Property("ValueType")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.HasKey("ValueTypeId")
+ .HasName("PK__ValueTyp__A51E9C5AEA096123");
+
+ b.ToTable("ValueTypes");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.WebJobSubscriptionStatus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("ID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Description")
+ .IsUnicode(false)
+ .HasColumnType("varchar(max)");
+
+ b.Property("InsertDate")
+ .HasColumnType("datetime");
+
+ b.Property("SubscriptionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SubscriptionStatus")
+ .HasMaxLength(225)
+ .IsUnicode(false)
+ .HasColumnType("varchar(225)");
+
+ b.HasKey("Id");
+
+ b.ToTable("WebJobSubscriptionStatus");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.KnownUsers", b =>
+ {
+ b.HasOne("Marketplace.SaaS.Accelerator.DataAccess.Entities.Roles", "Role")
+ .WithMany("KnownUsers")
+ .HasForeignKey("RoleId")
+ .IsRequired()
+ .HasConstraintName("FK__KnownUser__RoleI__619B8048");
+
+ b.Navigation("Role");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.MeteredAuditLogs", b =>
+ {
+ b.HasOne("Marketplace.SaaS.Accelerator.DataAccess.Entities.Subscriptions", "Subscription")
+ .WithMany("MeteredAuditLogs")
+ .HasForeignKey("SubscriptionId")
+ .HasConstraintName("FK__MeteredAu__Subsc__628FA481");
+
+ b.Navigation("Subscription");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.MeteredDimensions", b =>
+ {
+ b.HasOne("Marketplace.SaaS.Accelerator.DataAccess.Entities.Plans", "Plan")
+ .WithMany("MeteredDimensions")
+ .HasForeignKey("PlanId")
+ .HasConstraintName("FK__MeteredDi__PlanI__6383C8BA");
+
+ b.Navigation("Plan");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.MeteredPlanSchedulerManagement", b =>
+ {
+ b.HasOne("Marketplace.SaaS.Accelerator.DataAccess.Entities.MeteredDimensions", "MeteredDimensions")
+ .WithMany("MeteredPlanSchedulerManagements")
+ .HasForeignKey("DimensionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Marketplace.SaaS.Accelerator.DataAccess.Entities.SchedulerFrequency", "SchedulerFrequency")
+ .WithMany("MeteredPlanSchedulerManagements")
+ .HasForeignKey("FrequencyId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Marketplace.SaaS.Accelerator.DataAccess.Entities.Plans", "Plan")
+ .WithMany("MeteredPlanSchedulerManagements")
+ .HasForeignKey("PlanId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Marketplace.SaaS.Accelerator.DataAccess.Entities.Subscriptions", "Subscriptions")
+ .WithMany("MeteredPlanSchedulerManagements")
+ .HasForeignKey("SubscriptionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("MeteredDimensions");
+
+ b.Navigation("Plan");
+
+ b.Navigation("SchedulerFrequency");
+
+ b.Navigation("Subscriptions");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.SubscriptionAuditLogs", b =>
+ {
+ b.HasOne("Marketplace.SaaS.Accelerator.DataAccess.Entities.Subscriptions", "Subscription")
+ .WithMany("SubscriptionAuditLogs")
+ .HasForeignKey("SubscriptionId")
+ .HasConstraintName("FK__Subscript__Subsc__6477ECF3");
+
+ b.Navigation("Subscription");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Subscriptions", b =>
+ {
+ b.HasOne("Marketplace.SaaS.Accelerator.DataAccess.Entities.Users", "User")
+ .WithMany("Subscriptions")
+ .HasForeignKey("UserId")
+ .HasConstraintName("FK__Subscript__UserI__656C112C");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.MeteredDimensions", b =>
+ {
+ b.Navigation("MeteredPlanSchedulerManagements");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Plans", b =>
+ {
+ b.Navigation("MeteredDimensions");
+
+ b.Navigation("MeteredPlanSchedulerManagements");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Roles", b =>
+ {
+ b.Navigation("KnownUsers");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.SchedulerFrequency", b =>
+ {
+ b.Navigation("MeteredPlanSchedulerManagements");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Subscriptions", b =>
+ {
+ b.Navigation("MeteredAuditLogs");
+
+ b.Navigation("MeteredPlanSchedulerManagements");
+
+ b.Navigation("SubscriptionAuditLogs");
+ });
+
+ modelBuilder.Entity("Marketplace.SaaS.Accelerator.DataAccess.Entities.Users", b =>
+ {
+ b.Navigation("Subscriptions");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/DataAccess/Migrations/20240312055030_baseline751.cs b/src/DataAccess/Migrations/20240312055030_baseline751.cs
new file mode 100644
index 00000000..8b5b6c87
--- /dev/null
+++ b/src/DataAccess/Migrations/20240312055030_baseline751.cs
@@ -0,0 +1,20 @@
+using Marketplace.SaaS.Accelerator.DataAccess.Migrations.Custom;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Marketplace.SaaS.Accelerator.DataAccess.Migrations
+{
+ public partial class baseline751 : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.BaselineV751_SeedData();
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.BaselineV751_DeSeedData();
+ }
+ }
+}
diff --git a/src/DataAccess/Migrations/Custom/BaselineV751_Seed.cs b/src/DataAccess/Migrations/Custom/BaselineV751_Seed.cs
new file mode 100644
index 00000000..1bcbed1e
--- /dev/null
+++ b/src/DataAccess/Migrations/Custom/BaselineV751_Seed.cs
@@ -0,0 +1,35 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Query.Internal;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Marketplace.SaaS.Accelerator.DataAccess.Migrations.Custom
+{
+ internal static class BaselineV751_Seed
+ {
+ public static void BaselineV751_SeedData(this MigrationBuilder migrationBuilder)
+ {
+ var seedDate = DateTime.Now;
+ migrationBuilder.Sql(@$"
+ IF NOT EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'ValidateWebhookJwtToken')
+ BEGIN
+ INSERT [dbo].[ApplicationConfiguration] ( [Name], [Value], [Description]) VALUES ( N'ValidateWebhookJwtToken', N'true', N'Validates JWT token when webhook event is recieved.')
+ END
+ GO");
+ }
+
+ public static void BaselineV751_DeSeedData(this MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.Sql(@$"
+
+ IF EXISTS (SELECT * FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'ValidateWebhookJwtToken')
+ BEGIN
+ DELETE FROM [dbo].[ApplicationConfiguration] WHERE [Name] = 'ValidateWebhookJwtToken'
+ END
+ GO");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Services/Utilities/ValidateJwtToken.cs b/src/Services/Utilities/ValidateJwtToken.cs
new file mode 100644
index 00000000..c0100e70
--- /dev/null
+++ b/src/Services/Utilities/ValidateJwtToken.cs
@@ -0,0 +1,76 @@
+using Microsoft.IdentityModel.Protocols.OpenIdConnect;
+using Microsoft.IdentityModel.Protocols;
+using Microsoft.IdentityModel.Tokens;
+using System;
+using System.IdentityModel.Tokens.Jwt;
+using System.Threading;
+using System.Threading.Tasks;
+using Marketplace.SaaS.Accelerator.Services.Configurations;
+using System.Security.Claims;
+
+namespace Marketplace.SaaS.Accelerator.Services.Utilities;
+
+public class ValidateJwtToken
+{
+
+ private readonly SaaSApiClientConfiguration _saasapiConfiguration;
+
+ public ValidateJwtToken(SaaSApiClientConfiguration saasapiConfiguration)
+ {
+ _saasapiConfiguration = saasapiConfiguration;
+ }
+
+ public async Task ValidateTokenAsync(string token)
+ {
+ var configurationManager = new ConfigurationManager(
+ $"https://login.microsoftonline.com/{_saasapiConfiguration.TenantId}/.well-known/openid-configuration",
+ new OpenIdConnectConfigurationRetriever(),
+ new HttpDocumentRetriever());
+ var openIdConfig = await configurationManager.GetConfigurationAsync(CancellationToken.None);
+ var signingKeys = openIdConfig.SigningKeys;
+ var audience = _saasapiConfiguration.ClientId;
+
+ var validationParameters = new TokenValidationParameters
+ {
+ //Issuer can change based on the token version. So we are not validating the issuer
+ ValidateIssuer = false,
+ ValidateAudience = true,
+ ValidAudience = audience,
+ ValidateIssuerSigningKey = true,
+ IssuerSigningKeys = signingKeys,
+ ValidateLifetime = true,
+ ClockSkew = TimeSpan.FromMinutes(0)
+ };
+
+ var handler = new JwtSecurityTokenHandler();
+
+ //validate aud, expiry and signature using jwt validation handler
+ ClaimsPrincipal claimsPrincipal = handler.ValidateToken(token, validationParameters, out var validatedToken);
+
+ // Get the 'tid' claim
+ Claim tidClaim = claimsPrincipal.FindFirst("tid");
+ string tenantId = tidClaim?.Value;
+
+ Claim tidfullClaim = claimsPrincipal.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid");
+ string tidfull = tidfullClaim?.Value;
+
+ //For the old token v1, its 'appId' and for v2 its 'azp'. Try get both.
+ Claim azpClaim = claimsPrincipal.FindFirst("azp");
+ string azpId = azpClaim?.Value;
+
+ Claim appidClaim = claimsPrincipal.FindFirst("appid");
+ string appId = appidClaim?.Value;
+
+ //return false if the tenantId or azpId or appId is not matching with the configuration
+ if ((tenantId != _saasapiConfiguration.TenantId) && (tidfull != _saasapiConfiguration.TenantId))
+ {
+ throw new Exception("TenantId is not matching with the configuration");
+ }
+ if ((azpId != _saasapiConfiguration.Resource) && (appId != _saasapiConfiguration.Resource))
+ {
+ throw new Exception("azpId or appId is not matching with the configuration");
+ }
+
+ return true;
+ }
+}