Skip to content

Commit

Permalink
Add doc on LDAP-based authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesChenX committed Jan 14, 2024
1 parent 6e26490 commit 4d8a2f5
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 14 deletions.
89 changes: 76 additions & 13 deletions turms-docs/src/server/module/identity-access-management.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
# Identity and Access Management

## Login authentication and authorization
## Login Authentication and Authorization

Turms not only provides a built-in identity and access management mechanism, but also supports user-defined identity and access management implementation based on plug-ins.

### Related configuration

| config name | default value | description |
| Property | Default Value | Description |
| -------------------------------------------------------- | ------------- | ------------------------------------------------------------ |
| turms.gateway.session.identity-access-management.enabled | true | Whether to enable the identity and access management mechanism. <br />If the value is `false`, turn off the Turms built-in identity and access management mechanism and user-based plug-in custom identity and access management implementation, and allow any user to log in, and authorize them to send any type of request |
| turms.gateway.session.identity-access-management.type | password | The type of Turms built-in identity and access management mechanism used. The type can be `noop`, `password`, `jwt`, `http`. See below for details |
| turms.gateway.session.identity-access-management.type | password | The type of Turms built-in identity and access management mechanism used. The type can be `noop`, `password`, `jwt`, `http` and `ldap`. See below for details |

### Built-in identity and access management mechanism

#### 1. NOOP

Turn off the built-in identity and access management mechanism, and allow any user to log in, and authorize it to send any request type.

##### Related configuration items
##### Related Properties

* turms.gateway.session.identity-access-management.type=noop

#### 2. Key-based authentication
#### 2. Password-based authentication

User authentication is based on the password in the `user` collection in the MongoDB built by the Turms server. Authorization implementation is not currently supported.

##### Related configuration items
##### Related Properties

* turms.gateway.session.identity-access-management.type=password

#### 3. Based on JWT authentication
#### 3. JWT-based Authentication

The JWT token contains the user's authentication and authorization information.

##### work process
##### Workflow

```mermaid
sequenceDiagram
Expand Down Expand Up @@ -139,9 +139,9 @@ in:
* `TYPING_STATUS`: input status related resources
* `RESOURCE`: storage resource related resources

##### Related configuration items
##### Related Properties

| config name | default value | description |
| Property | Default Value | Description |
| ------------------------------------------------------------ | ------------------------- | ------------------------------------------------------------ |
| turms.gateway.session.identity-access-management.type | password | Set to `jwt` to enable JWT-based identity and access management |
| turms.service.message.check-if-target-active-and-not-deleted | true | When using the `JWT` mechanism, you need to set this configuration item to `false`, otherwise because it does not exist in the Turms database the user, so the user will not be able to send messages |
Expand All @@ -164,7 +164,7 @@ in:

The HTTP response contains the user's authentication and authorization information.

##### work process
##### Workflow

```mermaid
sequenceDiagram
Expand Down Expand Up @@ -213,9 +213,9 @@ t-->>c: OK if authenticated

The meanings of `authenticated` and `statements` fields are the same as those of the corresponding statements in the JWT text above, so I won’t repeat them here.

##### Related configuration items
##### Related Properties

| config name | default value | description |
| Property | Default Value | Description |
| ------------------------------------------------------------ | ------------------------- | ------------------------------------------------------------ |
| turms.gateway.session.identity-access-management.type | password | Set to `http` to enable identity and access management based on external HTTP responses |
| turms.service.message.check-if-target-active-and-not-deleted | true | When using the `HTTP` mechanism, you need to set this configuration item to `false`, otherwise because it does not exist in the Turms database the user, so the user will not be able to send messages |
Expand All @@ -227,6 +227,69 @@ The meanings of `authenticated` and `statements` fields are the same as those of
| turms.gateway.session.identity-access-management.http.authentication.response-expectation.headers | | Match the value in the response header, if the match is successful, continue to other matches, otherwise the authentication fails |
| turms.gateway.session.identity-access-management.http.authentication.response-expectation.body-fields | { "authenticated": true } | Match this value in the response body, if the match is successful, continue with other matches , otherwise authentication fails |

#### 5. LDAP-based Authentication

##### Workflow

```mermaid
sequenceDiagram
participant c as Client Application
participant t as turms-gateway
participant l as LDAP Server
c->>t: login
t->>l: search user DN by user ID
l-->>t: result entries
alt count is 0
t-->>c: unauthenticated
else count is more than 1
t-->>c: internal error
else count is 1
t->>l: bind by found user DN and password
l-->>t: result code
alt result code is 49
t-->>c: unauthenticated
else result code is 0
t-->>c: authenticated
else
t-->>c: internal error
end
end
```

1. The client sends a login request to the turms-gateway server through the Turms client login interface `turmsClient.userService.login`.

2. Upon receiving the login request from the client, the turms-gateway will use the `userId` parameter from the login request, along with the properties configured in the turms-gateway system (such as `baseDn` and `searchFilter` mentioned later in this document) to construct a search request to LDAP, in order to search the user's DN corresponding to the `userId`.

3. When the turms-gateway receives the search result from LDAP, it will verify the number of entries in the search result:

1. If the number is 0, it indicates that the account does not exist, and as a result, the client will receive an unauthorized response.
2. If the number is 1, it indicates that the `userId` in the user's login request matches a corresponding DN. The turms-gateway will use this user's DN and the `password` parameter from the user's login request to send a bind login to the LDAP server:
1. If the result code is 49 (invalid credentials), the client will receive an unauthorized response.
2. If the result code is 0 (successful login), the client will receive an authorized response.
3. If it is any other result code, the client will receive a system internal error response.
3. If the number is greater than 1, it indicates an error in the system-configured `searchFilter` property, requiring reconfiguration, and as a result, the system will respond with an internal error.

**Note: The Turms user ID for an LDAP user is configured by the LDAP system administrator and is not configured by the Turms server. It is required that this value must be greater than 0, with no other conditions imposed.**

##### Related Properties

| Property | Default Value | Description |
| ------------------------------------------------------------ | --------------- | ------------------------------------------------------------ |
| turms.gateway.session.identity-access-management.type | password | Set to `ldap` to enable LDAP-based identity and access management |
| turms.gateway.session.identity-access-management.ldap.base-dn | "" | Base DN. For example, `dc=turms,dc=im` |
| turms.gateway.session.identity-access-management.ldap.admin.host | localhost | LDAP server host for administrative operations |
| turms.gateway.session.identity-access-management.ldap.admin.port | 389 | LDAP server port for administrative operations |
| turms.gateway.session.identity-access-management.ldap.admin.ssl.... | | SSL-related properties for administrative operations in LDAP |
| turms.gateway.session.identity-access-management.ldap.admin.username | "" | Administrator username |
| turms.gateway.session.identity-access-management.ldap.admin.password | "" | Administrator password |
| turms.gateway.session.identity-access-management.ldap.user.host | localhost | LDAP server address for user-related operations |
| turms.gateway.session.identity-access-management.ldap.user.port | 389 | LDAP server port for user-related operations |
| turms.gateway.session.identity-access-management.ldap.user.ssl.... | | SSL-related properties for user-related operations in LDAP |
| turms.gateway.session.identity-access-management.ldap.user.search-filter | "uid=${userId}" | Search filter. The turms-gateway matches the corresponding user DN in the LDAP system based on this search filter. `${userId}` is the user ID placeholder, which will be replaced with the `userId` from the user's login request when the filter is used. |

**Note: The "administrator" mentioned in properties does not necessarily refer to the LDAP system administrator. It simply requires the specified LDAP user to have permission to search for entries in the system.**

### Plug-in-based custom identity and access management implementation

Authentication plugin interface: `im.turms.gateway.infra.plugin.extension.UserAuthenticator`
Expand Down
65 changes: 64 additions & 1 deletion turms-docs/src/zh-CN/server/module/identity-access-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Turms既提供了内置的身份与访问管理机制,也支持用户基于插
| 配置名 | 默认值 | 说明 |
| -------------------------------------------------------- | -------- | ------------------------------------------------------------ |
| turms.gateway.session.identity-access-management.enabled | true | 是否开启身份与访问管理机制。<br />如果该值为`false`,则关闭Turms内置的身份与访问管理机制与用户基于插件自定义身份与访问管理实现,并允许任意用户登陆,与授权其发送任意请求类型 |
| turms.gateway.session.identity-access-management.type | password | 使用的Turms内置身份与访问管理机制类型,其类型可以为`noop``password``jwt``http`。具体见下文 |
| turms.gateway.session.identity-access-management.type | password | 使用的Turms内置身份与访问管理机制类型,其类型可以为`noop``password``jwt``http``LDAP`。具体见下文 |

### 内置的身份与访问管理机制

Expand Down Expand Up @@ -227,6 +227,69 @@ t-->>c: OK if authenticated
| turms.gateway.session.identity-access-management.http.authentication.response-expectation.headers | | 在响应头中匹配该值,如果匹配成功,则继续进行其他匹配,否则认证失败 |
| turms.gateway.session.identity-access-management.http.authentication.response-expectation.body-fields | { "authenticated": true } | 在响应正文中匹配该值,如果匹配成功,则继续进行其他匹配,否则认证失败 |

#### 5. 基于LDAP认证

##### 工作流程

```mermaid
sequenceDiagram
participant c as Client Application
participant t as turms-gateway
participant l as LDAP Server
c->>t: login
t->>l: search user DN by user ID
l-->>t: result entries
alt count is 0
t-->>c: unauthenticated
else count is more than 1
t-->>c: internal error
else count is 1
t->>l: bind by found user DN and password
l-->>t: result code
alt result code is 49
t-->>c: unauthenticated
else result code is 0
t-->>c: authenticated
else
t-->>c: internal error
end
end
```

1. 客户端通过Turms客户端登陆接口`turmsClient.userService.login`向turms-gateway服务端发送登陆请求。

2. turms-gateway获取到客户端发来的登陆请求参数后,会使用登陆请求中的`userId`参数,与turms-gateway系统中配置的参数(如下文将会提到的`baseDn``searchFilter`),去构造LDAP中的search请求,以查询`userId`对应的用户DN。

3. 当turms-gateway获取到LDAP响应的search结果时,turms-gateway会校验search结果的entries数量:

1. 如果数量为0,则说明账号不存在,因此响应客户端未授权;
2. 如果数量为1,则说明用户登陆请求中的`userId`匹配到了对应的DN。turms-gateway会使用该用户DN与用户登陆请求中的`password`参数,向LDAP服务端发送bind登陆操作:
1. 如果结果码(result code)为49(无效凭证),则响应客户端未授权。
2. 如果状态码为0(登陆成功0,则响应客户端已授权。
3. 如果为其他状态码,则响应客户端系统内部异常。
3. 如果数量大于1,则说明系统配置的`searchFilter`参数异常,需要重新配置,因此响应系统内部异常。

**注意:一个LDAP用户的Turms用户ID值是由LDAP系统管理员配置的,并不是由Turms服务端配置的,且要求该值必须大于0,无其他条件限制。**

##### 相关配置项

| 配置名 | 默认值 | 说明 |
| ------------------------------------------------------------ | --------------- | ------------------------------------------------------------ |
| turms.gateway.session.identity-access-management.type | password | 设置为`ldap`以开启基于LDAP的身份与访问管理机制 |
| turms.gateway.session.identity-access-management.ldap.base-dn | "" | 基准目录。如`dc=turms,dc=im` |
| turms.gateway.session.identity-access-management.ldap.admin.host | localhost | 用于管理员相关操作的LDAP服务端地址 |
| turms.gateway.session.identity-access-management.ldap.admin.port | 389 | 用于管理员相关操作的LDAP服务端端口号 |
| turms.gateway.session.identity-access-management.ldap.admin.ssl.... | | 用于管理员相关操作的LDAP的SSL相关配置 |
| turms.gateway.session.identity-access-management.ldap.admin.username | "" | 管理员用户名 |
| turms.gateway.session.identity-access-management.ldap.admin.password | "" | 管理员密码 |
| turms.gateway.session.identity-access-management.ldap.user.host | localhost | 用于用户相关操作的LDAP服务端地址 |
| turms.gateway.session.identity-access-management.ldap.user.port | 389 | 用于用户相关操作的LDAP服务端端口号 |
| turms.gateway.session.identity-access-management.ldap.user.ssl.... | | 用于用户相关操作的LDAP的SSL相关配置 |
| turms.gateway.session.identity-access-management.ldap.user.search-filter | "uid=${userId}" | 搜索过滤条件。turms-gateway根据该搜索语句去LDAP系统中匹配对应的用户DN。<br />`${userId}`是用户ID占位符,在条件被使用时,会被替换成用户登陆请求中的`userId`|

**提醒:配置中提到的`管理员`其实并不一定要是LDAP系统的管理员,只要被指定的LDAP用户拥有search查询系统中条目的权限即可。**

### 基于插件的自定义身份与访问管理实现

认证插件接口:`im.turms.gateway.infra.plugin.extension.UserAuthenticator`
Expand Down

0 comments on commit 4d8a2f5

Please sign in to comment.