ASP.NET Integration
The NexNet.Asp package integrates NexNet servers into ASP.NET Core applications. It plugs into middleware pipelines, enabling dependency injection, authentication, and reverse proxy support via WebSocket and HttpSocket transports.
Advantages
Integrating through ASP.NET Core provides:
- SSL/TLS termination at the reverse proxy, reducing cryptographic overhead on the application server
- Centralized traffic management for security policies (rate limiting, IP allowlisting, header validation)
- Consistent logging, monitoring, and metrics collection at the proxy level
- An additional layer for DDoS mitigation and protection against common web vulnerabilities
- Additional authentication with the connection prior to handing it to the NexNet server
Server Setup
var builder = WebApplication.CreateBuilder(args);
// Set up forwarded headers for proxy support
builder.Services.Configure<ForwardedHeadersOptions>(o =>
o.ForwardedHeaders = ForwardedHeaders.All);
// Optionally add authentication (Bearer shown for simplicity)
builder.Services.AddAuthentication().AddBearerToken("BearerTokenScheme", ...);
builder.Services.AddAuthorization();
// Register the NexNet server in DI — enables constructor injection on ServerNexus
builder.Services.AddNexusServer<ServerNexus, ServerNexus.ClientProxy>();
var app = builder.Build();
// Enable headers and authentication middleware
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
// Start the NexNet server on an HTTP endpoint
// Use UseWebSocketNexusServerAsync for WebSocket transport instead
await app.UseHttpSocketNexusServerAsync<ServerNexus, ServerNexus.ClientProxy>(c =>
{
c.Path = "/nexus";
// Optionally enable ASP.NET authentication
c.AspEnableAuthentication = true;
c.AspAuthenticationScheme = "BearerTokenScheme";
}).StartAsync(app.Lifetime.ApplicationStopped);
Client Connection
// Use WebSocketClientConfig for WebSocket transport
var config = new HttpSocketClientConfig
{
// Change to ws:// or wss:// for WebSocket connections
Url = new Uri("http://127.0.0.1:9001/nexus"),
// Optional authentication header
AuthenticationHeader = new AuthenticationHeaderValue("Bearer", "SecretTokenValue")
};
var client = ClientNexus.CreateClient(config, new ClientNexus());
await client.ConnectAsync();
For https:///wss:// URLs, SslClientAuthenticationOptions on the client config sets the client certificate and server certificate validation. See TLS and Certificates.
Client Certificates
When Kestrel terminates TLS and accepts client certificates, the certificate reaches the nexus as Context.RemoteCertificate for both WebSocket and HttpSocket sessions:
builder.WebHost.ConfigureKestrel(options => options.ListenAnyIP(9001, listen =>
listen.UseHttps(new HttpsConnectionAdapterOptions
{
ServerCertificate = serverCertificate,
ClientCertificateMode = ClientCertificateMode.AllowCertificate,
// Accept any certificate here and decide in the nexus, e.g. against an enrolled fingerprint.
ClientCertificateValidation = (_, _, _) => true,
})));
- The value is
HttpContext.Connection.ClientCertificatewhen the connection is accepted. NexNet does not callGetClientCertificateAsync, so withClientCertificateMode.DelayCertificatethe session sees no certificate. - When a reverse proxy terminates TLS, the application server never sees the client certificate and
Context.RemoteCertificateis null.
The ASP.NET Principal
The principal of the HTTP request that opened the connection (HttpContext.User) reaches the nexus as Context.User (ClaimsPrincipal?) for WebSocket and HttpSocket sessions. It is readable in OnAuthenticate, OnConnected and every invocation:
protected override ValueTask<IIdentity?> OnAuthenticate(ReadOnlyMemory<byte> authToken)
{
var user = Context.User;
if (user?.Identity?.IsAuthenticated == true && user.IsInRole("admin"))
return new ValueTask<IIdentity?>(new UserIdentity(user.Identity.Name!));
return new ValueTask<IIdentity?>((IIdentity?)null);
}
- With
AspEnableAuthentication = trueit is the principal ofAspAuthenticationScheme(or the default scheme when none is set); a request that fails it is answered 401 and never reaches the nexus. - With
AspEnableAuthentication = falseit is whatever the pipeline set, for exampleUseAuthenticationwith a default scheme; otherwise ASP.NET's empty, unauthenticated principal. - It is captured once when the connection is accepted and is not re-validated during the session. Only the principal is kept, not the
HttpContext. - It is extra input, not the session's identity: with
Authenticate = true,OnAuthenticatestill decides, and returning null refuses the connection.Context.Identityis whatOnAuthenticatereturns. Context.Useris null for TCP, TLS, UDS and QUIC sessions and in a client nexus.
Reverse Proxy Configuration
Nginx
A configuration that supports both WebSocket upgrades and HttpSocket connections:
server {
server_name example.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
The HttpSocket upgrade token is nexnet-httpsockets; the configuration above forwards it because it passes the client's Upgrade header through.
See Also
- Transports — Transport selection guide and comparison
- Authentication — NexNet-level authentication (can be combined with ASP.NET auth)