Skip to content

Commit

Permalink
feat: implement persistent token based remember me mechanism (#6131)
Browse files Browse the repository at this point in the history
#### What type of PR is this?
/kind feature
/area core
/milestone 2.17.x

#### What this PR does / why we need it:
新增基于持久化 Token 的 RememberMe 机制

本次更新引入了一种新的 RememberMe 机制,该机制基于持久化 Token,以增强安全性和管理灵活性。在此之前,RememberMe 功能通过以下方式生成 Token,并将其作为 cookie 发送回客户端:
```
 username + ":" + expiryTime + ":" + algorithmName + ":"
   + algorithmHex(username + ":" + expiryTime + ":" + password + ":" + key)
```
此方法的优点在于无需存储 Token 就可以进行验证,并且用户密码的更改会自动使 Token 失效。然而,它的主要缺点是缺乏管理能力,例如无法手动撤销 Token。

鉴于最新的设备管理需求(见 PR #6100),我们需要一种支持设备撤销(revoke)的机制。因此,我们采用了持久化 Token 的方式,并通过随机生成的方法来提高安全性,而不将用户名和密码直接签名在 Token 中。新的 Token 格式如下:
```
base64(tokenValue:series)
```
此更改将为系统带来更高的安全保障和更灵活的管理选项,特别是在需要高度控制和监管设备访问时。

#### Does this PR introduce a user-facing change?
```release-note
引入基于持久化 Token 的新 RememberMe 机制以增强安全性和管理灵活性,升级后需要重新登录
```
  • Loading branch information
guqing authored Jun 26, 2024
1 parent 3f94cfc commit ae6724a
Show file tree
Hide file tree
Showing 22 changed files with 2,240 additions and 23 deletions.
353 changes: 349 additions & 4 deletions api-docs/openapi/v3_0/aggregated.json
Original file line number Diff line number Diff line change
Expand Up @@ -12403,6 +12403,243 @@
]
}
},
"/apis/security.halo.run/v1alpha1/remembermetokens": {
"get": {
"description": "List RememberMeToken",
"operationId": "listRememberMeToken",
"parameters": [
{
"description": "Page number. Default is 0.",
"in": "query",
"name": "page",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"description": "Size number. Default is 0.",
"in": "query",
"name": "size",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"description": "Label selector. e.g.: hidden!\u003dtrue",
"in": "query",
"name": "labelSelector",
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "Field selector. e.g.: metadata.name\u003d\u003dhalo",
"in": "query",
"name": "fieldSelector",
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
"in": "query",
"name": "sort",
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
}
],
"responses": {
"200": {
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/RememberMeTokenList"
}
}
},
"description": "Response remembermetokens"
}
},
"tags": [
"RememberMeTokenV1alpha1"
]
},
"post": {
"description": "Create RememberMeToken",
"operationId": "createRememberMeToken",
"requestBody": {
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/RememberMeToken"
}
}
},
"description": "Fresh remembermetoken"
},
"responses": {
"200": {
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/RememberMeToken"
}
}
},
"description": "Response remembermetokens created just now"
}
},
"tags": [
"RememberMeTokenV1alpha1"
]
}
},
"/apis/security.halo.run/v1alpha1/remembermetokens/{name}": {
"delete": {
"description": "Delete RememberMeToken",
"operationId": "deleteRememberMeToken",
"parameters": [
{
"description": "Name of remembermetoken",
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Response remembermetoken deleted just now"
}
},
"tags": [
"RememberMeTokenV1alpha1"
]
},
"get": {
"description": "Get RememberMeToken",
"operationId": "getRememberMeToken",
"parameters": [
{
"description": "Name of remembermetoken",
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/RememberMeToken"
}
}
},
"description": "Response single remembermetoken"
}
},
"tags": [
"RememberMeTokenV1alpha1"
]
},
"patch": {
"description": "Patch RememberMeToken",
"operationId": "patchRememberMeToken",
"parameters": [
{
"description": "Name of remembermetoken",
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/JsonPatch"
}
}
}
},
"responses": {
"200": {
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/RememberMeToken"
}
}
},
"description": "Response remembermetoken patched just now"
}
},
"tags": [
"RememberMeTokenV1alpha1"
]
},
"put": {
"description": "Update RememberMeToken",
"operationId": "updateRememberMeToken",
"parameters": [
{
"description": "Name of remembermetoken",
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/RememberMeToken"
}
}
},
"description": "Updated remembermetoken"
},
"responses": {
"200": {
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/RememberMeToken"
}
}
},
"description": "Response remembermetokens updated just now"
}
},
"tags": [
"RememberMeTokenV1alpha1"
]
}
},
"/apis/storage.halo.run/v1alpha1/attachments": {
"get": {
"description": "List Attachment",
Expand Down Expand Up @@ -19022,12 +19259,12 @@
},
"visible": {
"type": "string",
"default": "PUBLIC",
"enum": [
"PUBLIC",
"INTERNAL",
"PRIVATE"
],
"default": "PUBLIC"
]
}
}
},
Expand Down Expand Up @@ -19524,6 +19761,114 @@
}
}
},
"RememberMeToken": {
"required": [
"apiVersion",
"kind",
"metadata",
"spec"
],
"type": "object",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"$ref": "#/components/schemas/Metadata"
},
"spec": {
"$ref": "#/components/schemas/RememberMeTokenSpec"
}
}
},
"RememberMeTokenList": {
"required": [
"first",
"hasNext",
"hasPrevious",
"items",
"last",
"page",
"size",
"total",
"totalPages"
],
"type": "object",
"properties": {
"first": {
"type": "boolean",
"description": "Indicates whether current page is the first page."
},
"hasNext": {
"type": "boolean",
"description": "Indicates whether current page has previous page."
},
"hasPrevious": {
"type": "boolean",
"description": "Indicates whether current page has previous page."
},
"items": {
"type": "array",
"description": "A chunk of items.",
"items": {
"$ref": "#/components/schemas/RememberMeToken"
}
},
"last": {
"type": "boolean",
"description": "Indicates whether current page is the last page."
},
"page": {
"type": "integer",
"description": "Page number, starts from 1. If not set or equal to 0, it means no pagination.",
"format": "int32"
},
"size": {
"type": "integer",
"description": "Size of each page. If not set or equal to 0, it means no pagination.",
"format": "int32"
},
"total": {
"type": "integer",
"description": "Total elements.",
"format": "int64"
},
"totalPages": {
"type": "integer",
"description": "Indicates total pages.",
"format": "int64"
}
}
},
"RememberMeTokenSpec": {
"required": [
"series",
"tokenValue",
"username"
],
"type": "object",
"properties": {
"lastUsed": {
"type": "string",
"format": "date-time"
},
"series": {
"minLength": 1,
"type": "string"
},
"tokenValue": {
"minLength": 1,
"type": "string"
},
"username": {
"minLength": 1,
"type": "string"
}
}
},
"RemoveOperation": {
"required": [
"op",
Expand Down Expand Up @@ -20723,12 +21068,12 @@
},
"visible": {
"type": "string",
"default": "PUBLIC",
"enum": [
"PUBLIC",
"INTERNAL",
"PRIVATE"
],
"default": "PUBLIC"
]
}
}
},
Expand Down
Loading

0 comments on commit ae6724a

Please sign in to comment.