|
| 1 | +--- |
| 2 | +title: include file |
| 3 | +description: .NET websocket callback security |
| 4 | +services: azure-communication-services |
| 5 | +author: Kunaal Punjabi |
| 6 | +ms.service: azure-communication-services |
| 7 | +ms.subservice: azure-communication-services |
| 8 | +ms.date: 05/06/2025 |
| 9 | +ms.topic: include |
| 10 | +ms.topic: include file |
| 11 | +ms.author: kpunjabi |
| 12 | +--- |
| 13 | + |
| 14 | +## Websocket code sample |
| 15 | + |
| 16 | +This sample code demonstrates how to configure OIDC client to validate webhook payload using JWT |
| 17 | + |
| 18 | +```csharp |
| 19 | +// 1. Load OpenID Connect metadata |
| 20 | +var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>( |
| 21 | + builder.Configuration["OpenIdConfigUrl"], |
| 22 | + new OpenIdConnectConfigurationRetriever()); |
| 23 | + |
| 24 | +var openIdConfig = await configurationManager.GetConfigurationAsync(); |
| 25 | +// 2. Register JWT authentication |
| 26 | +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) |
| 27 | + .AddJwtBearer(options => |
| 28 | + { |
| 29 | + options.Configuration = openIdConfig; |
| 30 | + options.TokenValidationParameters = new TokenValidationParameters |
| 31 | + { |
| 32 | + ValidAudience = builder.Configuration["AllowedAudience"] |
| 33 | + }; |
| 34 | + }); |
| 35 | + |
| 36 | +builder.Services.AddAuthorization(); |
| 37 | + |
| 38 | +var app = builder.Build(); |
| 39 | +// 3. Use authentication & authorization middleware |
| 40 | +app.UseAuthentication(); |
| 41 | +app.UseAuthorization(); |
| 42 | + |
| 43 | +app.UseWebSockets(); |
| 44 | + |
| 45 | +// 4. WebSocket token validation manually in middleware |
| 46 | +app.Use(async (context, next) => |
| 47 | +{ |
| 48 | + if (context.Request.Path != "/ws") |
| 49 | + { |
| 50 | + await next(context); |
| 51 | + return; |
| 52 | + } |
| 53 | + |
| 54 | + if (!context.WebSockets.IsWebSocketRequest) |
| 55 | + { |
| 56 | + context.Response.StatusCode = StatusCodes.Status400BadRequest; |
| 57 | + await context.Response.WriteAsync("WebSocket connection expected."); |
| 58 | + return; |
| 59 | + } |
| 60 | + |
| 61 | + var result = await context.AuthenticateAsync(); |
| 62 | + if (!result.Succeeded) |
| 63 | + { |
| 64 | + context.Response.StatusCode = StatusCodes.Status401Unauthorized; |
| 65 | + await context.Response.WriteAsync("Unauthorized WebSocket connection."); |
| 66 | + return; |
| 67 | + } |
| 68 | + |
| 69 | + context.User = result.Principal; |
| 70 | + |
| 71 | + // Optional: Log headers |
| 72 | + var correlationId = context.Request.Headers["x-ms-call-correlation-id"].FirstOrDefault(); |
| 73 | + var callConnectionId = context.Request.Headers["x-ms-call-connection-id"].FirstOrDefault(); |
| 74 | + |
| 75 | + Console.WriteLine($"Authenticated WebSocket - Correlation ID: {correlationId ?? "not provided"}"); |
| 76 | + Console.WriteLine($"Authenticated WebSocket - CallConnection ID: {callConnectionId ?? "not provided"}"); |
| 77 | + |
| 78 | + // Now you can safely accept the WebSocket and process the connection |
| 79 | + // var webSocket = await context.WebSockets.AcceptWebSocketAsync(); |
| 80 | + // var mediaService = new AcsMediaStreamingHandler(webSocket, builder.Configuration); |
| 81 | + // await mediaService.ProcessWebSocketAsync(); |
| 82 | +}); |
| 83 | +``` |
0 commit comments