Table of Contents

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.ClientCertificate when the connection is accepted. NexNet does not call GetClientCertificateAsync, so with ClientCertificateMode.DelayCertificate the session sees no certificate.
  • When a reverse proxy terminates TLS, the application server never sees the client certificate and Context.RemoteCertificate is 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 = true it is the principal of AspAuthenticationScheme (or the default scheme when none is set); a request that fails it is answered 401 and never reaches the nexus.
  • With AspEnableAuthentication = false it is whatever the pipeline set, for example UseAuthentication with 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, OnAuthenticate still decides, and returning null refuses the connection. Context.Identity is what OnAuthenticate returns.
  • Context.User is 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)