Forward SignalR requests through the web app
This commit is contained in:
		
							parent
							
								
									992b58d4bc
								
							
						
					
					
						commit
						6933d9997d
					
				| @ -3,6 +3,5 @@ | ||||
| public class AppSettings | ||||
| { | ||||
|     public string PurchaseUrl { get; set; } | ||||
|     public string SignalrHubUrl { get; set; } | ||||
|     public bool UseCustomizationData { get; set; } | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| // Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used | ||||
| // Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 | ||||
| using Yarp.ReverseProxy.Forwarder; | ||||
| 
 | ||||
| internal static class Extensions | ||||
| { | ||||
|     public static void AddHealthChecks(this IServiceCollection services, IConfiguration configuration) | ||||
| @ -82,4 +84,27 @@ internal static class Extensions | ||||
|             options.Scope.Add("webhooks"); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     public static IEndpointConventionBuilder MapForwardSignalR(this WebApplication app) | ||||
|     { | ||||
|         // Forward the SignalR traffic to the bff | ||||
|         var destination = app.Configuration.GetRequiredValue("PurchaseUrl"); | ||||
|         var authTransformer = new BffAuthTransfomer(); | ||||
|         var requestConfig = new ForwarderRequestConfig(); | ||||
| 
 | ||||
|         return app.MapForwarder("/hub/notificationhub/{**any}", destination, requestConfig, authTransformer); | ||||
|     } | ||||
| 
 | ||||
|     private sealed class BffAuthTransfomer : HttpTransformer | ||||
|     { | ||||
|         public override async ValueTask TransformRequestAsync(HttpContext httpContext, HttpRequestMessage proxyRequest, string destinationPrefix, CancellationToken cancellationToken) | ||||
|         { | ||||
|             // Set the access token as a bearer token for the outgoing request | ||||
|             var accessToken = await httpContext.GetTokenAsync("access_token"); | ||||
| 
 | ||||
|             proxyRequest.Headers.Authorization = new("Bearer", accessToken); | ||||
| 
 | ||||
|             await base.TransformRequestAsync(httpContext, proxyRequest, destinationPrefix, cancellationToken); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| 
 | ||||
| builder.AddServiceDefaults(); | ||||
| 
 | ||||
| builder.Services.AddHttpForwarder(); | ||||
| builder.Services.AddControllersWithViews(); | ||||
| 
 | ||||
| builder.Services.AddHealthChecks(builder.Configuration); | ||||
| @ -28,6 +29,7 @@ app.UseAuthorization(); | ||||
| app.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}"); | ||||
| app.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}"); | ||||
| app.MapControllers(); | ||||
| app.MapForwardSignalR(); | ||||
| 
 | ||||
| WebContextSeed.Seed(app, app.Environment); | ||||
| 
 | ||||
|  | ||||
| @ -86,35 +86,23 @@ | ||||
| 
 | ||||
|     @RenderSection("scripts", required: false) | ||||
| 
 | ||||
| 
 | ||||
|     @using Microsoft.AspNetCore.Authentication; | ||||
|     @using Microsoft.Extensions.Options | ||||
|     @inject IOptions<AppSettings> settings | ||||
| 
 | ||||
|     <script type="text/javascript"> | ||||
|         if ('@User.Identity.IsAuthenticated' === 'True') { | ||||
|             var timerId; | ||||
| 
 | ||||
|             stablishConnection((conn) => registerNotificationHandlers(conn));                                   | ||||
|             connect(); | ||||
|         } | ||||
| 
 | ||||
|         function stablishConnection(cb) { | ||||
|         async function connect() { | ||||
|             let connection = new signalR.HubConnectionBuilder() | ||||
|                 .withUrl('@settings.Value.SignalrHubUrl/hub/notificationhub', { | ||||
|                     accessTokenFactory: () => { | ||||
|                         return "Authorization", getToken(); | ||||
|                     } | ||||
|                 }) | ||||
|                 .withUrl('/hub/notificationhub') | ||||
|                 .withAutomaticReconnect() | ||||
|                 .build(); | ||||
| 
 | ||||
|             connection.start().then(function () { | ||||
|                 console.log('User Registered to Signalr Hub'); | ||||
|                 cb(connection); | ||||
|             });        | ||||
|         } | ||||
|             await connection.start(); | ||||
| 
 | ||||
|             console.log('User Registered to Signalr Hub'); | ||||
| 
 | ||||
|         function registerNotificationHandlers(connection) { | ||||
|             connection.on("UpdatedOrderState", (message) => { | ||||
|                 toastr.success('Updated to status: ' + message.status, 'Order Id: ' + message.orderId); | ||||
|                 if (window.location.pathname.split("/").pop() === 'Order') { | ||||
| @ -123,10 +111,6 @@ | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         function getToken() { | ||||
|             return '@Context.GetTokenAsync("access_token").Result'; | ||||
|         } | ||||
| 
 | ||||
|         function refreshOrderList() { | ||||
|             clearTimeout(timerId); | ||||
|             timerId = setTimeout(function () { | ||||
|  | ||||
| @ -24,6 +24,7 @@ | ||||
|     <PackageReference Include="BuildBundlerMinifier" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" /> | ||||
|     <PackageReference Include="Yarp.ReverseProxy" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user