Forward SignalR requests through the web app
This commit is contained in:
		
							parent
							
								
									992b58d4bc
								
							
						
					
					
						commit
						6933d9997d
					
				| @ -3,6 +3,5 @@ | |||||||
| public class AppSettings | public class AppSettings | ||||||
| { | { | ||||||
|     public string PurchaseUrl { get; set; } |     public string PurchaseUrl { get; set; } | ||||||
|     public string SignalrHubUrl { get; set; } |  | ||||||
|     public bool UseCustomizationData { 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 | // 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 | // Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 | ||||||
|  | using Yarp.ReverseProxy.Forwarder; | ||||||
|  | 
 | ||||||
| internal static class Extensions | internal static class Extensions | ||||||
| { | { | ||||||
|     public static void AddHealthChecks(this IServiceCollection services, IConfiguration configuration) |     public static void AddHealthChecks(this IServiceCollection services, IConfiguration configuration) | ||||||
| @ -82,4 +84,27 @@ internal static class Extensions | |||||||
|             options.Scope.Add("webhooks"); |             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.AddServiceDefaults(); | ||||||
| 
 | 
 | ||||||
|  | builder.Services.AddHttpForwarder(); | ||||||
| builder.Services.AddControllersWithViews(); | builder.Services.AddControllersWithViews(); | ||||||
| 
 | 
 | ||||||
| builder.Services.AddHealthChecks(builder.Configuration); | builder.Services.AddHealthChecks(builder.Configuration); | ||||||
| @ -28,6 +29,7 @@ app.UseAuthorization(); | |||||||
| app.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}"); | app.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}"); | ||||||
| app.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}"); | app.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}"); | ||||||
| app.MapControllers(); | app.MapControllers(); | ||||||
|  | app.MapForwardSignalR(); | ||||||
| 
 | 
 | ||||||
| WebContextSeed.Seed(app, app.Environment); | WebContextSeed.Seed(app, app.Environment); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -86,35 +86,23 @@ | |||||||
| 
 | 
 | ||||||
|     @RenderSection("scripts", required: false) |     @RenderSection("scripts", required: false) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     @using Microsoft.AspNetCore.Authentication; |  | ||||||
|     @using Microsoft.Extensions.Options |  | ||||||
|     @inject IOptions<AppSettings> settings |  | ||||||
| 
 |  | ||||||
|     <script type="text/javascript"> |     <script type="text/javascript"> | ||||||
|         if ('@User.Identity.IsAuthenticated' === 'True') { |         if ('@User.Identity.IsAuthenticated' === 'True') { | ||||||
|             var timerId; |             var timerId; | ||||||
| 
 | 
 | ||||||
|             stablishConnection((conn) => registerNotificationHandlers(conn));                                   |             connect(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         function stablishConnection(cb) { |         async function connect() { | ||||||
|             let connection = new signalR.HubConnectionBuilder() |             let connection = new signalR.HubConnectionBuilder() | ||||||
|                 .withUrl('@settings.Value.SignalrHubUrl/hub/notificationhub', { |                 .withUrl('/hub/notificationhub') | ||||||
|                     accessTokenFactory: () => { |  | ||||||
|                         return "Authorization", getToken(); |  | ||||||
|                     } |  | ||||||
|                 }) |  | ||||||
|                 .withAutomaticReconnect() |                 .withAutomaticReconnect() | ||||||
|                 .build(); |                 .build(); | ||||||
| 
 | 
 | ||||||
|             connection.start().then(function () { |             await connection.start(); | ||||||
|                 console.log('User Registered to Signalr Hub'); | 
 | ||||||
|                 cb(connection); |             console.log('User Registered to Signalr Hub'); | ||||||
|             });        |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         function registerNotificationHandlers(connection) { |  | ||||||
|             connection.on("UpdatedOrderState", (message) => { |             connection.on("UpdatedOrderState", (message) => { | ||||||
|                 toastr.success('Updated to status: ' + message.status, 'Order Id: ' + message.orderId); |                 toastr.success('Updated to status: ' + message.status, 'Order Id: ' + message.orderId); | ||||||
|                 if (window.location.pathname.split("/").pop() === 'Order') { |                 if (window.location.pathname.split("/").pop() === 'Order') { | ||||||
| @ -123,10 +111,6 @@ | |||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         function getToken() { |  | ||||||
|             return '@Context.GetTokenAsync("access_token").Result'; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         function refreshOrderList() { |         function refreshOrderList() { | ||||||
|             clearTimeout(timerId); |             clearTimeout(timerId); | ||||||
|             timerId = setTimeout(function () { |             timerId = setTimeout(function () { | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ | |||||||
|     <PackageReference Include="BuildBundlerMinifier" /> |     <PackageReference Include="BuildBundlerMinifier" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" /> |     <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" /> |     <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" /> | ||||||
|  |     <PackageReference Include="Yarp.ReverseProxy" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| 
 | 
 | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user