Skip to content

Commit

Permalink
Add logic to validate token on webhook notification (#671)
Browse files Browse the repository at this point in the history
* add validate webhook filter

* added logic for validate jwt token

* add appconfig to validate token and db migration

* manually validating tenant and saas resource
  • Loading branch information
santhoshb-msft authored Mar 19, 2024
1 parent ccde4eb commit d59b49d
Show file tree
Hide file tree
Showing 6 changed files with 1,357 additions and 5 deletions.
51 changes: 49 additions & 2 deletions src/CustomerSite/Controllers/WebHook/AzureWebhookController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -63,6 +64,22 @@ public class AzureWebhookController : ControllerBase
/// </summary>
private readonly SubscriptionService subscriptionService;

/// <summary>
/// The JWT token validation.
/// </summary>
private readonly ValidateJwtToken validateJwtToken;

/// <summary>
/// The ApplicationConfig Repository.
/// </summary>
private readonly IApplicationConfigRepository applicationConfigRepository;

/// <summary>
/// The ApplicationConfig service.
/// </summary>
private readonly ApplicationConfigService applicationConfigService;


/// <summary>
/// Initializes a new instance of the <see cref="AzureWebhookController"/> class.
/// </summary>
Expand All @@ -72,7 +89,16 @@ public class AzureWebhookController : ControllerBase
/// <param name="planRepository">The plan repository.</param>
/// <param name="subscriptionsRepository">The subscriptions repository.</param>
/// <param name="configuration">The SaaSApiClientConfiguration from ENV</param>
public AzureWebhookController(IApplicationLogRepository applicationLogRepository, IWebhookProcessor webhookProcessor, ISubscriptionLogRepository subscriptionsLogRepository, IPlansRepository planRepository, ISubscriptionsRepository subscriptionsRepository, SaaSApiClientConfiguration configuration)
/// <param name="validateJwtToken">The validateJwtToken utility</param>
/// <param name="applicationConfigRepository">The application config repository</param>
public AzureWebhookController(IApplicationLogRepository applicationLogRepository,
IWebhookProcessor webhookProcessor,
ISubscriptionLogRepository subscriptionsLogRepository,
IPlansRepository planRepository,
ISubscriptionsRepository subscriptionsRepository,
SaaSApiClientConfiguration configuration,
ValidateJwtToken validateJwtToken,
IApplicationConfigRepository applicationConfigRepository)
{
this.applicationLogRepository = applicationLogRepository;
this.subscriptionsRepository = subscriptionsRepository;
Expand All @@ -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);
}

/// <summary>
Expand All @@ -94,6 +123,24 @@ public async Task<IActionResult> 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);
Expand All @@ -106,7 +153,7 @@ public async Task<IActionResult> 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();
}
Expand Down
6 changes: 3 additions & 3 deletions src/CustomerSite/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ public void ConfigureServices(IServiceCollection services)
services
.AddTransient<IClaimsTransformation, CustomClaimsTransformation>()
.AddScoped<ExceptionHandlerAttribute>()
.AddScoped<RequestLoggerActionFilter>()
;
.AddScoped<RequestLoggerActionFilter>();

if (!Uri.TryCreate(config.FulFillmentAPIBaseURL, UriKind.Absolute, out var fulfillmentBaseApi))
{
Expand All @@ -115,7 +114,8 @@ public void ConfigureServices(IServiceCollection services)

services
.AddSingleton<IFulfillmentApiService>(new FulfillmentApiService(new MarketplaceSaaSClient(fulfillmentBaseApi, creds), config, new FulfillmentApiClientLogger()))
.AddSingleton<SaaSApiClientConfiguration>(config);
.AddSingleton<SaaSApiClientConfiguration>(config)
.AddSingleton<ValidateJwtToken>();

services
.AddDbContext<SaasKitContext>(options => options.UseSqlServer(this.Configuration.GetConnectionString("DefaultConnection")));
Expand Down
Loading

0 comments on commit d59b49d

Please sign in to comment.