Skip to content

Commit 58d2f98

Browse files
authored
Add additional documentation about client authentication (#3009)
* test * docs * Revert "test" This reverts commit ecd1189. * Update Authentication.md * Update Authentication.md * Update index.md * prefer async
1 parent 8defa55 commit 58d2f98

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

docs/Authentication.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
Authentication
2+
===
3+
4+
There are multiple ways of connecting to a Redis server, depending on the authentication model. The simplest
5+
(but least secure) approach is to use the `default` user, with no authentication, and no transport security.
6+
This is as simple as:
7+
8+
``` csharp
9+
var muxer = await ConnectionMultiplexer.ConnectAsync("myserver"); // or myserver:1241 to use a custom port
10+
```
11+
12+
This approach is often used for local transient servers - it is simple, but insecure. But from there,
13+
we can get more complex!
14+
15+
TLS
16+
===
17+
18+
If your server has TLS enabled, SE.Redis can be instructed to use it. In some cases (AMR, etc), the
19+
library will recognize the endpoint address, meaning: *you do not need to do anything*. To
20+
*manually* enable TLS, the `ssl` token can be used:
21+
22+
``` csharp
23+
var muxer = await ConnectionMultiplexer.ConnectAsync("myserver,ssl=true");
24+
```
25+
26+
This will work fine if the server is using a server-certificate that is already trusted by the local
27+
machine. If this is *not* the case, we need to tell the library about the server. This requires
28+
the `ConfigurationOptions` type:
29+
30+
``` csharp
31+
var options = ConfigurationOptions.Parse("myserver,ssl=true");
32+
// or: var options = new ConfigurationOptions { Endpoints = { "myserver" }, Ssl = true };
33+
// TODO configure
34+
var muxer = await ConnectionMultiplexer.ConnectAsync(options);
35+
```
36+
37+
If we have a local *issuer* public certificate (commonly `ca.crt`), we can use:
38+
39+
``` csharp
40+
options.TrustIssuer(caPath);
41+
```
42+
43+
Alternatively, in advanced scenarios: to provide your own custom server validation, the `options.CertificateValidation` callback
44+
can be used; this uses the normal [`RemoteCertificateValidationCallback`](https://learn.microsoft.com/dotnet/api/system.net.security.remotecertificatevalidationcallback)
45+
API.
46+
47+
Usernames and Passwords
48+
===
49+
50+
Usernames and passwords can be specified with the `user` and `password` tokens, respectively:
51+
52+
``` csharp
53+
var muxer = await ConnectionMultiplexer.ConnectAsync("myserver,ssl=true,user=myuser,password=mypassword");
54+
```
55+
56+
If no `user` is provided, the `default` user is assumed. In some cases, an authentication-token can be
57+
used in place of a classic password.
58+
59+
Client certificates
60+
===
61+
62+
If the server is configured to require a client certificate, this can be supplied in multiple ways.
63+
If you have a local public / private key pair (such as `MyUser2.crt` and `MyUser2.key`), the
64+
`options.SetUserPemCertificate(...)` method can be used:
65+
66+
``` csharp
67+
config.SetUserPemCertificate(
68+
userCertificatePath: userCrtPath,
69+
userKeyPath: userKeyPath
70+
);
71+
```
72+
73+
If you have a single `pfx` file that contains the public / private pair, the `options.SetUserPfxCertificate(...)`
74+
method can be used:
75+
76+
``` csharp
77+
config.SetUserPfxCertificate(
78+
userCertificatePath: userCrtPath,
79+
password: filePassword // optional
80+
);
81+
```
82+
83+
Alternatively, in advanced scenarios: to provide your own custom client-certificate lookup, the `options.CertificateSelection` callback
84+
can be used; this uses the normal
85+
[`LocalCertificateSelectionCallback`](https://learn.microsoft.com/dotnet/api/system.net.security.remotecertificatevalidationcallback)
86+
API.
87+
88+
User certificates with implicit user authentication
89+
===
90+
91+
Historically, the client certificate only provided access to the server, but as the `default` user. From 8.6,
92+
the server can be configured to use client certificates to provide user identity. This replaces the
93+
usage of passwords, and requires:
94+
95+
- An 8.6+ server, configured to use TLS with client certificates mapped - typically using the `CN` of the certificate as the user.
96+
- A matching `ACL` user account configured on the server, that is enabled (`on`) - i.e. the `ACL LIST` command should
97+
display something like `user MyUser2 on sanitize-payload ~* &* +@all` (the details will vary depending on the user permissions).
98+
- At the client: access to the client certificate pair.
99+
100+
For example:
101+
102+
``` csharp
103+
string certRoot = // some path to a folder with ca.crt, MyUser2.crt and MyUser2.key
104+
105+
var options = ConfigurationOptions.Parse("myserver:6380");
106+
options.SetUserPemCertificate(// automatically enables TLS
107+
userCertificatePath: Path.Combine(certRoot, "MyUser2.crt"),
108+
userKeyPath: Path.Combine(certRoot, "MyUser2.key"));
109+
options.TrustIssuer(Path.Combine(certRoot, "ca.crt"));
110+
await using var conn = await ConnectionMultiplexer.ConnectAsync(options);
111+
112+
// prove we are connected as MyUser2
113+
var user = (string?)await conn.GetDatabase().ExecuteAsync("acl", "whoami");
114+
Console.WriteLine(user); // writes "MyUser2"
115+
```
116+
117+
More info
118+
===
119+
120+
For more information:
121+
122+
- [Redis Security](https://redis.io/docs/latest/operate/oss_and_stack/management/security/)
123+
- [ACL](https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/)
124+
- [TLS](https://redis.io/docs/latest/operate/oss_and_stack/management/security/encryption/)

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Documentation
3131
---
3232

3333
- [Server](Server) - running a redis server
34+
- [Authentication](Authentication) - connecting to a Redis server with user authentication
3435
- [Basic Usage](Basics) - getting started and basic usage
3536
- [Async Timeouts](AsyncTimeouts) - async timeouts and cancellation
3637
- [Configuration](Configuration) - options available when connecting to redis

0 commit comments

Comments
 (0)