# 访问控制

> Control access to Unity Gaming Services by creating rules to restrict service APIs.

您可以通过 [Access Control 服务](/services/access-control.md)来控制对 Unity Gaming Services（Unity 游戏服务）(UGS) 的访问（包括对 Cloud Code 的访问）。

通过使用 Access Control，您可以创建规则来限制访问不应提供给玩家的服务 API。

> **Note:**
>
> 如果您允许玩家访问模块，游戏的安全性会降低。如需了解更多信息，请参阅[服务器权威](/cloud-code.md)。

## 控制玩家对 Cloud Code 模块的访问示例##control-player-access-to-cloud-code-modules-example

以下示例演示了如何创建基于项目的策略来拒绝对 Cloud Code 服务 API 的访问。您可以将 Cloud Code C# 模块关联到触发器，同时拒绝玩家的直接请求，从而提高游戏的安全性。您可以使用 [UGS CLI 工具](https://services.docs.unity.com/guides/ugs-cli/latest/access/Access%20Command%20Line/overview/)创建访问策略。

## 先决条件##prerequisites

首先需要创建具有所需访问角色的服务帐户，并配置 [UGS CLI](https://services.docs.unity.com/guides/ugs-cli/latest/general/get-started/install-the-cli/)。

### 使用服务帐户进行身份验证##authenticate-using-a-service-account

在调用 Scheduling 和 Triggers 服务之前，需要使用服务帐户进行身份验证。

1. 导航到 [Unity Dashboard](https://cloud.unity.com)。
2. 选择 **Administration（管理）**> **Service Accounts（服务帐户）**。
3. 选择 **New（新建）** 按钮并输入服务帐户的名称和描述。
4. 选择 **Create（创建）**。

添加产品角色并创建密钥：

1. 选择 **Manage product roles（管理产品角色）**。
2. 将以下角色添加到服务帐户：

* 从 LiveOps 下拉选单中，选择 **Triggers Configuration Editor（Triggers 配置编辑者）**、**Triggers Configuration Viewer（Triggers 配置查看者）**、**Scheduler Configuration Editor（Scheduler 配置编辑者）** 和 **Scheduler Configuration Viewer（Scheduler 配置查看者）**。
* 从 Admin（管理）下拉选单中，选择 **Unity Environments Viewer（Unity 环境查看者）**、**Project Resource Policy Editor（项目资源策略编辑者）** 和 **Project Resource Policy Reader（项目资源策略读取者）**。

3. 选择 **Save（保存）**。
4. 选择 **Add Key（添加密钥）**。
5. 使用 base64 编码方式对 **Key ID（密钥 ID）** 和 **Secret key（密钥）** 进行编码。格式为“key\_id:secret\_key”。请记下此值。

如需了解更多信息，请参阅[身份验证](../authentication)。

### 配置 UGS CLI##configure-the-ugs-cli

按照以下步骤操作以开始使用 UGS CLI：

1. [安装 UGS CLI](https://services.docs.unity.com/guides/ugs-cli/latest/general/get-started/install-the-cli/)。

2. 使用以下命令配置您的 Project ID 和环境：
   `ugs config set project-id <your-project-id>`
   `ugs config set environment-name <your-environment-name>`

3. 使用您先前创建的服务帐户进行身份验证。如需了解更多信息，请参阅[接受身份验证](https://services.docs.unity.com/guides/ugs-cli/latest/general/get-started/get-authenticated/)。

### 创建模块终端##create-a-module-endpoint

[创建](/cloud-code/modules/how-to-guides/write-modules.md)一个 Cloud Code 模块向项目中所有已连接的玩家广播一条消息。

如需了解更多信息，请参阅[发送推送消息](/cloud-code/modules/how-to-guides/push-messages.md)。

```csharp
using Microsoft.Extensions.DependencyInjection;
using Unity.Services.CloudCode.Core;
using Unity.Services.CloudCode.Apis;

namespace HelloWorld
{
    public class HelloWorld
    {
        [CloudCodeFunction("SendProjectMessage")]
        public async Task SendProjectMessage(IExecutionContext context, PushClient pushClient, string message, string messageType)
        {
            await pushClient.SendProjectMessageAsync(context, message, messageType);
        }
    }

    public class ModuleConfig : ICloudCodeSetup
    {
        public void Setup(ICloudCodeConfig config)
        {
            config.Dependencies.AddSingleton(PushClient.Create());
        }
    }
}
```

部署该模块。

请参阅[部署 Hello World](/cloud-code/modules/getting-started.md#deploy-the-module) 以了解如何部署模块。

### 创建 Access Control 项目策略以限制访问##create-an-access-control-project-policy-to-restrict-access

创建一个包含以下内容的 `project-policy.json` 文件，从而创建一个策略，拒绝玩家直接访问模块终端。

```json
{
  "statements": [
    {
      "Sid": "DenyPlayerAccessForSendingMessageToProject",
      "Resource": "urn:ugs:cloud-code:/v1/projects/*/modules/HelloWorld/SendProjectMessage",
      "Principal": "Player",
      "Action": ["*"],
      "Effect": "Deny"
    }
  ]
}
```

使用 UGS CLI 工具将此策略应用于您的项目：

`ugs access upsert-project-policy project-policy.json`

测试此策略是否成功拒绝了玩家在[以玩家身份通过身份验证后](/cloud-code/modules/how-to-guides/authentication.md#authenticate-players)直接向 `SendProjectMessage` 模块终端发出的请求。

```bash
curl 'https://cloud-code.services.api.unity.com/v1/projects/<PROJECT_ID>/players/<PLAYER_ID>/modules/HelloWorld/SendProjectMessage' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER_TOKEN>' \
--data '{
"params": {
"message": "hello"
}
}'
```

如果成功应用此策略，该请求应返回包含 `403` HTTP 状态代码的响应：

```json
{
    "status": 403,
    "title": "Forbidden",
    "type": "https://services.docs.unity.com/docs/errors/#56",
    "requestId": "b815d154-91f5-470e-a8ef-76c3c8ec7c13",
    "detail": "Access has been restricted",
    "code": 56
}
```

测试 Cloud Code 模块是否能在使用服务帐户对相同请求进行身份验证时执行。若要继续，需获取无状态令牌，并将其用作请求中的持有者令牌。

如需了解更多信息，请参阅 [Cloud Code Client API 持有者身份验证](/cloud-code/modules/how-to-guides/authentication.md#cloud-code-client-api-bearer-authentication)。

```bash
curl 'https://cloud-code.services.api.unity.com/v1/projects/<PROJECT_ID>/modules/HelloWorld/SendProjectMessage' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER_TOKEN>' \
--data '{
"params": {
"message": "hello"
}
}'
```

如果请求成功，Cloud Code 应该会以 `200` HTTP 状态代码进行响应。

```json
{
  "output":null
}
```

### 设置 Scheduling 和 Triggers##set-up-scheduling-and-triggers

您可以设置计划和触发器来调用 `SendProjectMessage` 模块终端。

#### 创建计划配置##create-a-schedule-configuration

运行 `new-file` 命令在本地创建计划配置：

```bash
ugs scheduler new-file schedule-config
```

使用以下配置来更新 `schedule-config.sched` 文件：

```json
{
  "$schema": "https://ugs-config-schemas.unity3d.com/v1/schedules.schema.json",
  "Configs": {
    "send-project-message": {
      "EventName": "announcement",
      "Type": "one-time",
      "Schedule": "2024-08-28T00:00:00Z",
      "PayloadVersion": 1,
      "Payload": "{\"message\": \"hello\"}"
    }
  }
}
```

> **Note:**
>
> **注意**：确保 `schedule` 时间戳是未来的时间。

#### 创建触发器配置##create-a-trigger-configuration

运行 `new-file` 命令在本地创建触发器配置：

```bash
ugs triggers new-file triggers-config
```

要创建在 `announcement` 事件触发时调用 `SendProjectMessage` 模块终端的触发器，请使用以下配置来更新 `triggers-config.tr` 文件：

```json
{
  "$schema": "https://ugs-config-schemas.unity3d.com/v1/triggers.schema.json",
  "Configs": [
    {
      "Name": "announcement-trigger",
      "EventType": "com.unity.services.scheduler.announcement.v1",
      "ActionUrn": "urn:ugs:cloud-code:HelloWorld/SendProjectMessage",
      "ActionType": "cloud-code"
    }
  ]
}
```

#### 部署配置##deploy-the-configurations

使用 UGS CLI 工具部署文件：

```bash
ugs deploy <path-to-config-files>
```

如果配置正确，触发器应在触发 `announcement` 事件时调用 `SendProjectMessage` 模块终端。
