Skip to content

Commit 3a8beaf

Browse files
committed
finish
1 parent bf91be5 commit 3a8beaf

File tree

1 file changed

+122
-1
lines changed

1 file changed

+122
-1
lines changed

security-compatibility-with-mysql.md

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,125 @@ The support for TLS authentication is configured differently. For detailed infor
145145

146146
`tidb_auth_token` is a JSON Web Token (JWT) based authentication method used in TiDB Cloud, which can be used for self-hosted after configuration. Different from authentication based on password like `mysql_native_password` or `caching_sha2_password`, when creating users in `tidb_auth_token`, no custom password is needed. When authenticating users with `tidb_auth_token` for logging to TiDB, a signed token is required instead of password, which simplifying the authentication process and improving the security.
147147

148-
JWT consists of 3 parts: Header, Payload, and Signature.
148+
JWT consists of 3 parts: Header, Payload, and Signature. After being encoded using base64, they are concatenated into a stirng separated by dots (`.`).
149+
150+
The Header describe the meta data of the JWT, including 3 parameters:
151+
152+
* `alg` means the algorithm for signature, default as `RS256`
153+
* `typ` means the type of token, unified as `JWT`
154+
* `kid` means the key id for generating token signature
155+
156+
Here is an example for Header:
157+
158+
```json
159+
{
160+
"alg": "RS256",
161+
"kid": "the-key-id-0",
162+
"typ": "JWT"
163+
}
164+
```
165+
166+
The Payload is the main part of JWT, which stores the user information in *clains*. These claims are required by `tidb_auth_token` users:
167+
168+
* `iss`: if `TOKEN_ISSUER` is not set or set to empty when [`CREATE USER`](/sql-statements/sql-statement-create-user.md), this claim is not required; or this claim should be the same as the setting value
169+
* `sub`: this claim is required to be the same as the user name
170+
* `iat`: means `issued at`. In TiDB, it is required not to be later than the time of authentication and not earlier than 15 minutes before authentication
171+
* `exp`: means `expiration time`. If it is earlier than the time of authentication, the authentication fails
172+
173+
In addition, some other claim(s) are required in TiDB:
174+
175+
* `email`: The email can be specified when creating user by `ATTRIBUTE '{"email": "[email protected]"}`. If no email was giving when creating user, this claim should be set as an empty string; or it should be the same as the specified value
176+
177+
Here are some valid Payload examples:
178+
179+
```json
180+
{
181+
"email": "[email protected]",
182+
"exp": 1703305494,
183+
"iat": 1703304594,
184+
"iss": "issuer-abc",
185+
186+
}
187+
```
188+
189+
The Payload is allowed not to contain `iss` claim:
190+
191+
```json
192+
{
193+
"email": "",
194+
"exp": 1703305494,
195+
"iat": 1703304594,
196+
197+
}
198+
```
199+
200+
The Signature signs the above two parts.
201+
202+
> **Warning:**
203+
>
204+
> 1. The encoding of the Header and Payload in base64 is reversible. Please do not attach any sensitive information in them
205+
> 2. The `tidb_auth_token` authentication requires that the client supports [`mysql_clear_password`](https://dev.mysql.com/doc/refman/8.0/en/cleartext-pluggable-authentication.html) plugin to send the token to TiDB in clear text. Therefore, please [enale TLS between clients and servers](/enable-tls-between-clients-and-servers.md) before using `tidb_auth_token`
206+
207+
Here are the steps to config before using `tidb_auth_token`:
208+
209+
1. Config [`auth-token-jwks`](/tidb-configuration-file.md#auth-token-jwks-new-in-v640) and [`auth-token-refresh-interval`](/tidb-configuration-file.md#auth-token-refresh-interval-new-in-v640) in the configuration file
210+
2. Save the JWKS periodly to the path specified by `auth-token-jwks`
211+
3. Create a user with `tidb_auth_token`, and sepcify `iss` and `email` by `REQUIRE TOKEN_ISSUER` and `ATTRIBUTE '{"email": "[email protected]"}`
212+
4. Generate and sign a token used for authentication, authencating with mysql client's `mysql_clear_text` plugin
213+
214+
#### Example
215+
216+
1. Install JWT genration tool by `go install github.com/cbcwestwolf/generate_jwt`. This tool is only used for testing `tidb_auth_token`
217+
2. Get the example JWKS: `wget https://raw.githubusercontent.com/CbcWestwolf/generate_jwt/master/JWKS.json`
218+
3. Config the path of above JWKS in `config.toml`:
219+
220+
```toml
221+
[security]
222+
auth-token-jwks = "JWKS.json"
223+
```
224+
225+
4. start `tidb-server`
226+
5. create a user `[email protected]` with `tidb_auth_token`
227+
228+
```sql
229+
CREATE USER '[email protected]' IDENTIFIED WITH 'tidb_auth_token' REQUIRE TOKEN_ISSUER 'issuer-abc' ATTRIBUTE '{"email": "[email protected]"}';
230+
```
231+
232+
##### Authentication
233+
234+
Generate a token by `generate_jwt`:
235+
236+
```text
237+
generate_jwt --kid "the-key-id-0" --sub "[email protected]" --email "[email protected]" --iss "issuer-abc"
238+
```
239+
240+
It prints the public key and token like:
241+
242+
```text
243+
-----BEGIN PUBLIC KEY-----
244+
MIIBCgKCAQEAq8G5n9XBidxmBMVJKLOBsmdOHrCqGf17y9+VUXingwDUZxRp2Xbu
245+
LZLbJtLgcln1lC0L9BsogrWf7+pDhAzWovO6Ai4Aybu00tJ2u0g4j1aLiDdsy0gy
246+
vSb5FBoL08jFIH7t/JzMt4JpF487AjzvITwZZcnsrB9a9sdn2E5B/aZmpDGi2+Is
247+
f5osnlw0zvveTwiMo9ba416VIzjntAVEvqMFHK7vyHqXbfqUPAyhjLO+iee99Tg5
248+
AlGfjo1s6FjeML4xX7sAMGEy8FVBWNfpRU7ryTWoSn2adzyA/FVmtBvJNQBCMrrA
249+
hXDTMJ5FNi8zHhvzyBKHU0kBTS1UNUbP9wIDAQAB
250+
-----END PUBLIC KEY-----
251+
252+
eyJhbGciOiJSUzI1NiIsImtpZCI6InRoZS1rZXktaWQtMCIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InVzZXJAcGluZ2NhcC5jb20iLCJleHAiOjE3MDMzMDU0OTQsImlhdCI6MTcwMzMwNDU5NCwiaXNzIjoiaXNzdWVyLWFiYyIsInN1YiI6InVzZXJAcGluZ2NhcC5jb20ifQ.T4QPh2hTB5on5xCuvtWiZiDTuuKvckggNHtNaovm1F4RvwUv15GyOqj9yMstE-wSoV5eLEcPC2HgE6eN1C6yH_f4CU-A6n3dm9F1w-oLbjts7aYCl8OHycVYnq609fNnb8JLsQAmd1Zn9C0JW899-WSOQtvjLqVSPe9prH-cWaBVDQXzUJKxwywQzk9v-Z1Njt9H3Rn9vvwwJEEPI16VnaNK38I7YG-1LN4fAG9jZ6Zwvz7vb_s4TW7xccFf3dIhWTEwOQ5jDPCeYkwraRXU8NC6DPF_duSrYJc7d7Nu9Z2cr-E4i1Rt_IiRTuIIzzKlcQGg7jd9AGEfGe_SowsA-w
253+
```
254+
255+
Copy the above token in the last line for authentication:
256+
257+
```Shell
258+
mycli -h 127.0.0.1 -P 4000 -u '[email protected]' -p '<the-token-generated>'
259+
```
260+
261+
Note that the mysql client here should support `mysql_clear_password` plugin. [mycli](https://www.mycli.net/) supports and enable this plugin default. If using [mysql command-line client](https://dev.mysql.com/doc/refman/8.0/en/mysql.html), an option `--enable-cleartext-plugin` is required to enable this plugin.
262+
263+
```Shell
264+
mysql -h 127.0.0.1 -P 4000 -u '[email protected]' -p'<the-token-generated>' --enable-cleartext-plugin
265+
```
266+
267+
If specifying wrong `--sub` when generating token, like `--sub "[email protected]`, the authentication using this token would fail.
268+
269+
You can encode and decode a token with the help of the debugger in [jwt.io](https://jwt.io/).

0 commit comments

Comments
 (0)