StackExchange.Redis

Authentication

There are multiple ways of connecting to a Redis server, depending on the authentication model. The simplest (but least secure) approach is to use the default user, with no authentication, and no transport security. This is as simple as:

var muxer = await ConnectionMultiplexer.ConnectAsync("myserver"); // or myserver:1241 to use a custom port

This approach is often used for local transient servers - it is simple, but insecure. But from there, we can get more complex!

TLS

If your server has TLS enabled, SE.Redis can be instructed to use it. In some cases (AMR, etc), the library will recognize the endpoint address, meaning: you do not need to do anything. To manually enable TLS, the ssl token can be used:

var muxer = await ConnectionMultiplexer.ConnectAsync("myserver,ssl=true");

This will work fine if the server is using a server-certificate that is already trusted by the local machine. If this is not the case, we need to tell the library about the server. This requires the ConfigurationOptions type:

var options = ConfigurationOptions.Parse("myserver,ssl=true");
// or: var options = new ConfigurationOptions { Endpoints = { "myserver" }, Ssl = true };
// TODO configure
var muxer = await ConnectionMultiplexer.ConnectAsync(options);

If we have a local issuer public certificate (commonly ca.crt), we can use:

options.TrustIssuer(caPath);

Alternatively, in advanced scenarios: to provide your own custom server validation, the options.CertificateValidation callback can be used; this uses the normal RemoteCertificateValidationCallback API.

Usernames and Passwords

Usernames and passwords can be specified with the user and password tokens, respectively:

var muxer = await ConnectionMultiplexer.ConnectAsync("myserver,ssl=true,user=myuser,password=mypassword");

If no user is provided, the default user is assumed. In some cases, an authentication-token can be used in place of a classic password.

Client certificates

If the server is configured to require a client certificate, this can be supplied in multiple ways. If you have a local public / private key pair (such as MyUser2.crt and MyUser2.key), the options.SetUserPemCertificate(...) method can be used:

config.SetUserPemCertificate(
    userCertificatePath: userCrtPath,
    userKeyPath: userKeyPath
);

If you have a single pfx file that contains the public / private pair, the options.SetUserPfxCertificate(...) method can be used:

config.SetUserPfxCertificate(
    userCertificatePath: userCrtPath,
    password: filePassword // optional
);

Alternatively, in advanced scenarios: to provide your own custom client-certificate lookup, the options.CertificateSelection callback can be used; this uses the normal LocalCertificateSelectionCallback API.

User certificates with implicit user authentication

Historically, the client certificate only provided access to the server, but as the default user. From 8.6, the server can be configured to use client certificates to provide user identity. This replaces the usage of passwords, and requires:

For example:

string certRoot = // some path to a folder with ca.crt, MyUser2.crt and MyUser2.key

var options = ConfigurationOptions.Parse("myserver:6380");
options.SetUserPemCertificate(// automatically enables TLS
    userCertificatePath: Path.Combine(certRoot, "MyUser2.crt"),
    userKeyPath: Path.Combine(certRoot, "MyUser2.key"));
options.TrustIssuer(Path.Combine(certRoot, "ca.crt"));
await using var conn = await ConnectionMultiplexer.ConnectAsync(options);

// prove we are connected as MyUser2
var user = (string?)await conn.GetDatabase().ExecuteAsync("acl", "whoami");
Console.WriteLine(user); // writes "MyUser2"

More info

For more information: