Using MessagePack protocol in the context of serverless Azure SignalR services - signalr

The following code works fine with my Azure SignalR Services (serverless mode) and I am able to receieve messages/events successfully.
var connection = new HubConnectionBuilder()
.WithUrl(connectionInfo.NegotiationUrl!, options =>
{
options.Headers.Add("x-ms-signalr-userid", "myuserid");
options.Headers.Add("x-functions-key", "mykey");
})
.WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromMilliseconds(5) })
.Build();
connection.Closed += excecption =>
{
return Task.CompletedTask;
};
connection.On("onMsg", (Action<object>)(message =>
{
Console.WriteLine(message)
}));
I referenced the .NET MessagePack NuGet package for SignalR and invoked .AddMessagePackProtocol() extension method in the hub connection builder per the code below but stop receiving messages from SignalR.
var connection = new HubConnectionBuilder()
.WithUrl(connectionInfo.NegotiationUrl!, options =>
{
options.Headers.Add("x-ms-signalr-userid", "myuserid");
options.Headers.Add("x-functions-key", "mykey");
})
.AddMessagePackProtocol()
.WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromMilliseconds(5) })
.Build();
Am I missing anything in this configuration? What is the right approach to solve this problem? I don't think if we need to do anything on Azure SignalR Service configuration to start getting messagePack packets.
I expect to receive the signalR messages when the message pack protocol is enabled.

The chosen Azure signalR service transport type is Persistent, and the messagePack protocol is not supported in this mode per this article.

Related

How to establish HTTPS/ssl/tls Backend <=> Frontend connection using angular 13?

I have a API-REST service in ASP.NET CORE web-api NET 6. I am using client certificate authentication with the following configuration.
builder.WebHost.ConfigureKestrel(options =>
{
options.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ServerCertificate = serverCertificate;
listenOptions.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
listenOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
listenOptions.CheckCertificateRevocation = false;
//listenOptions.AllowAnyClientCertificate();
listenOptions.ClientCertificateValidation = (certificate, chain, errors) =>
{
if (chain.Build(certificate))
//Add certificate verification
return true;
return false;
};
});
options.ListenLocalhost(7120, op =>
{
op.UseHttps(serverCertificate);
op.Protocols = HttpProtocols.Http1AndHttp2;
op.UseConnectionLogging();
});
});
It works perfectly from POSTMAN adding the client certificate issued by my CA and its intermediate certificate.
I get this error in Angular. (ERR_BAD_SSL_CLIENT_AUTH_CERT)
I have the CORS already configured.
How can I send the client's certificate from Angular to the backend or how do I establish communication?
there is no need that your frontend app (spa) knows any thing about tls or domain or IP your server has
you have environment variable
//development
baseUrl:'localhost:5001'
//production
// enviroment.prod.ts
baseUrl:'/api/'
when your in production build for it
simply do not use certificate for developement

Should GRPC net and Azure app service work

In this video for .Net 7 and GRPC
https://www.youtube.com/watch?v=et_2NBk4N4Y
the say that GRPC should work on azure linux app service.
I have implemented following this guide with no success.
https://github.com/Azure/app-service-linux-docs/blob/master/HowTo/gRPC/use_gRPC_with_dotnet.md
this is my program.cs
var builder = WebApplication.CreateBuilder(args);
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
#if Debug
builder.WebHost.ConfigureKestrel(options =>
{
// Setup a HTTP/2 endpoint without TLS.
options.ListenLocalhost(5253, o => o.Protocols =
HttpProtocols.Http2);
});
#endif
#if RELEASE
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenAnyIP(8080);
options.ListenAnyIP(5253, listenOptions =>
{
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
});
});
#endif
// Add services to the container.
builder.Services.AddGrpc();
builder.Services.AddGrpcReflection();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGrpcService<MobileAppsService>();
app.MapGrpcReflectionService();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
app.Run();
Try test with Postman and only get Error: Received RST_STREAM with code 0
all work run local.

How to use SignalR on multiple servers?

I have a chat app that I made with dotnet core, singalR, and react native. My chat is working well when I publish it on a single server. But when I get publish it in multiple servers by docker swarm. I get this error.
Unable to connect to the server with any of the available transports. WebSockets failed: Error: There was an error with the transport.
By this error message, the app is just sometimes working normally. When I leave the page and return back it is not working again.
I am using ubuntu server. I both aligned the versions of signalR on server and client. They are both using 5.0.3. I don't have proxy server in front of the app and I m using load balancing feature of docker swarm.
Configure Service
var tokenKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["TokenKey"]));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = tokenKey,
ValidateAudience = false,
ValidateIssuer = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
opt.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken))
{
if (path.StartsWithSegments("/chat")
|| path.StartsWithSegments("/dialog"))
{
context.Token = accessToken;
}
}
return Task.CompletedTask;
}
};
});
Configure Void
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chat", opt => { opt.Transports = HttpTransportType.WebSockets; });
endpoints.MapHub<DialogHub>("/dialog", opt => { opt.Transports = HttpTransportType.WebSockets; });
});
When scaling out SignalR to multiple servers, a shared data plane would be needed to manage distributed state, in addition to the network considerations.
As noted in the docs, Microsoft suggests either introducing a Redis backplane or delegating to their managed service, Azure SignalR.
An app that uses SignalR needs to keep track of all its connections,
which creates problems for a server farm. Add a server, and it gets
new connections that the other servers don't know about.
Having used Azure SignalR, it's fairly straightforward to integrate with an ASP.NET Core app. You then have offloaded all the overhead of managing connections from your app.

Asp core doesn't enforce client certificate

I have an API app created using asp core. I'm trying to enforce use of client certificates as described here.
I did tell Kestrel to require certificates in Program.cs:
webBuilder.ConfigureKestrel(o =>
{
o.ConfigureHttpsDefaults(o => o.ClientCertificateMode = ClientCertificateMode.RequireCertificate);
});
And I did add event handler in Startup.cs:
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
{
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = context =>
{
}
};
});
When I debug the API running locally it still doesn't require any certificates. If I provide certificate anyway, the breakpoint in the event handler is never hit.

asp.core windows authentication integration tests fails with No authentication handler is configured

I have a ASP.Core web app that uses windows authentication I am trying to setup integration tests for.
inside the startup the authorization is configured as follows
services.Configure<IISOptions>(options =>
{
options.ForwardWindowsAuthentication = true;
});
services.AddAuthorization(options =>
{
options.AddPolicy("SiteRead", policy => policy.RequireAssertion(
context => context.User.HasClaim(
x => x.Value == "groupSidHere"
)));
});
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
The test is as follows
var server = new TestServer(builder);
var client = server.CreateClient();
var response = await client.GetAsync("/");
response.EnsureSuccessStatusCode();
The test fails with the following response
InvalidOperationException: No authentication handler is configured to handle the scheme: Automatic
All the documentation I have been able to find for integration tests doesn't cover this scenario(windows auth). Has anyone found a solution to this?
See this issue, they say:
We ended up solving our need for Windows auth with TestServer by creating a little library that will inject some windows auth services into the pipeline to emulate the behavior provided by IIS - you can find it at
You will find their library "IntelliTect.AspNetCore.TestHost.WindowsAuth" here.
I faced the same issue, and that library worked for me!
And it actually inject real windows authentication data, not just a mock data.

Resources