pushnotifications-demo-aspnetcore
pushnotifications-demo-aspnetcore copied to clipboard
WebPush Notification Send Results in 403
Hello
I used your demo as a blueprint to implement the push subscriptions for our customers.
I can subscribe users, and also send notifications to them in my development environment. So i pushed it up to staging, but now i get the 403 with the same code. (with new subscriptions for the new environment).
Exception:
Received unexpected response code: 403 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() --- End of stack trace from previous location where exception was thrown --- at WebPush.WebPushClient.HandleResponse(HttpResponseMessage response, PushSubscription subscription) at WebPush.WebPushClient.<SendNotificationAsync>d__15.MoveNext() at WebPush.WebPushClient.<SendNotificationAsync>d__16.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Backend.Notifications.MessageHandler.NotificationBatchMessageHandler.<Handle>d__11.MoveNext() in /app/src/Backend/Notifications/MessageHandler/NotificationBatchMessageHandler.cs:line 93
For the Subscriptions, they are done via a website run in docker containers behind a Loadbalancer, the public endpoint of the Loadbalancer is served via Https, and the containers run on different machines in a private subnet.
The Communication between the Loadbalancers and Containers is established via HTTP.
Code to send Notifications:
var notification = GenerateNotification(batch.Template, account);
string notificationjson = string.Empty;
try
{
if (await _repo.RecordNotificationSent(subscription.Id, batch.Template.Id,
notification.NotificationId.ToString()))
{
notificationjson = JsonConvert.SerializeObject(notification);
_client = new WebPushClient();
await _client.SendNotificationAsync(ToWebPushSubscription(subscription),
notificationjson, _vapidDetails);
}
}
catch (WebPushException ex)
{
if(ex.Message == "Subscription no longer valid")
{
Logger?.LogInformation($"invalidate subscription {subscription.Id}");
await _ar.UnsubscribePushAsync(subscription);
}
else
{
Logger?.LogCritical(ex.Message, ex);
}
}
catch (Exception ex)
{
Logger?.LogCritical(ex.Message, ex);
}
...
private WebPush.PushSubscription ToWebPushSubscription(PushSubscription sub)
{
return new WebPush.PushSubscription(sub.Endpoint, sub.P256Dh, sub.Auth);
}
Environment Settings:
- dotnet core 1.1.1
- webpush version: 1.0.11
Development Environment:
- windows 10 Pro & VS Community 2019 16.2.2
Staging Environment:
- containers based on microsoft/dotnet:1.1.1-sdk
WebServer: Kestrel
Any Ideas what could cause this issue, and how to fix it?
Hi @epandasa, have you generated new VAPID keys for your staging environment?
Hi @mark-szabo,
i just tested it and yes my Code automatically generates new VAPID keys for each Environment/Tenant, and writes them to our Database.
private async Task<VapidDetails> CheckOrGenerateVapidDetails(string vapidSubject, string vapidPublicKey, string vapidPrivateKey, int tenantid)
{
if (string.IsNullOrEmpty(vapidSubject))
{
return null;
}
if (string.IsNullOrEmpty(vapidSubject) ||
string.IsNullOrEmpty(vapidPublicKey) ||
string.IsNullOrEmpty(vapidPrivateKey))
{
var vapidKeys = VapidHelper.GenerateVapidKeys();
vapidPublicKey = vapidKeys.PublicKey;
vapidPrivateKey = vapidKeys.PrivateKey;
await _tr.UpdateVapidDetailsAsync(tenantid, vapidSubject, vapidPublicKey,vapidPrivateKey);
}
return new VapidDetails(vapidSubject, vapidPublicKey, vapidPrivateKey);
}
This Code runs when no VAPID keys are given/generated on Startup in the current context, inside of my Push Controller.
public async Task<IActionResult> VapidPublicKey()
{
if(_vapidDetails == null)
{
_vapidDetails = await CheckOrGenerateVapidDetails(Request.Host.Host, null, null, _tenant.Id);
}
return Json(_vapidDetails.PublicKey);
}
......
public async Task<IActionResult> Subscribe([FromBody] PushSubscriptionViewModel model)
{
if (_vapidDetails == null)
{
_vapidDetails = await CheckOrGenerateVapidDetails($"https://{Request.Host}", null, null, _tenant.Id);
}
.....
}
@mark-szabo
I too am having a 403 issue with every environment besides my own. I have followed the demo set up almost to a "T". Including the service: https://github.com/MicrosoftEdge/pushnotifications-demo-aspnetcore/blob/master/PushnotificationsDemo/Services/PushService.cs
For my public and private key I saved it as env variable so that everything who pulls latest or when we push it to dev and up. Will have those keys as well.
I to this day do not have any issues receiving the notifications.
But in co-workers and dev environments. I get the same exact exception above. Any help will be more than appreciated! I have been banging my head against the wall.
From certs to appsettings to env variables to keys....I do not see any differences. What am I missing?!
I have the same trouble. I didn't change the project I just downloaded and ran it.
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
WebPush.WebPushException: Received unexpected response code: 403
at WebPush.WebPushClient.HandleResponse(HttpResponseMessage response, PushSubscription subscription)
at WebPush.WebPushClient.SendNotification(PushSubscription subscription, String payload, Dictionary`2 options)
at WebPush.WebPushClient.SendNotification(PushSubscription subscription, String payload, VapidDetails vapidDetails)
at PushnotificationsDemo.Services.PushService.Send(String userId, Notification notification) in /Users/gavrilyuc/Downloads/pushnotifications-demo-aspnetcore-master 2/PushnotificationsDemo/Services/PushService.cs:line 96
at PushnotificationsDemo.Services.PushService.Send(String userId, Notification notification) in /Users/gavrilyuc/Downloads/pushnotifications-demo-aspnetcore-master 2/PushnotificationsDemo/Services/PushService.cs:line 107
at PushnotificationsDemo.Controllers.PushController.Send(String userId, Notification notification, Nullable`1 delay) in /Users/gavrilyuc/Downloads/pushnotifications-demo-aspnetcore-master 2/PushnotificationsDemo/Controllers/PushController.cs:line 105
at lambda_method(Closure , Object )
at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at System.Threading.Tasks.ValueTask`1.get_Result()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Can you help me, anybody? @molant @mark-szabo @TASimpson
any updates on this?