

AWS 大型机现代化服务（托管运行时环境体验）不再向新客户开放。有关类似于 AWS 大型机现代化服务（托管运行时环境体验）的功能，请浏览 AWS 大型机现代化服务（自我管理体验）。现有客户可以继续正常使用该服务。有关更多信息，请参阅[AWS 大型机现代化可用性变更](https://docs.aws.amazon.com/m2/latest/userguide/mainframe-modernization-availability-change.html)。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 为 Gapwalk 应用程序配置安全性
<a name="ba-runtime-security"></a>

以下主题介绍如何保护 Gapwalk 应用程序。

您有责任提供正确的配置，以确保安全地使用适用于大型机的 Tr AWS ansform 框架。

默认情况下，会禁用所有与安全有关的特征。要启用身份验证（以及 CSRF、XSS、CSP 等），请将 `gapwalk-application.security` 设置为 `enabled`，将 `gapwalk-application.security.identity` 设置为 `oauth`。

**Topics**
+ [为 Gapwalk 应用程序配置 URI 可访问性](ba-runtime-filteringURIs.md)
+ [为 Gapwalk 应用程序配置身份验证](ba-runtime-auth.md)
+ [为大型机运行时 AWS 转换配置速率限制](ba-runtime-rate-limiting.md)

# 为 Gapwalk 应用程序配置 URI 可访问性
<a name="ba-runtime-filteringURIs"></a>

本主题介绍如何为 Gapwalk 应用程序配置过滤。 URIs 此特征不需要身份提供者（IdP）。

要屏蔽列表 URIs，请在现代化应用程序中`application-main.yml`添加以下两行，将*URI-1**URI-2*、等替换为要屏蔽 URIs 的。

```
gapwalk-application.security.filterURIs: enabled
gapwalk-application.security.blockedURIs: URI-1, URI-2, URI-3
```

# 为 Gapwalk 应用程序配置身份验证
<a name="ba-runtime-auth"></a>

要为您的 Gapwalk 应用程序配置 OAuth2 身份验证，您需要设置身份提供商 (IdP) 并将其与您的应用程序集成。本指南介绍了使用 Amazon Cognito 或 Keycloak 作为 IdP 的步骤。使用 Amazon Cognito，您可以使用 Cognito 用户池详细信息更新应用程序的配置文件。使用 Keycloak，您可以根据用户分配的 APIs 角色控制对应用程序和资源的访问权限。

**Topics**
+ [使用 Amazon Cognito 配置 Gapwalk OAuth2 身份验证](ba-runtime-auth-cognito.md)
+ [使用 Keycloak 配置 Gap OAuth2 walk 身份验证](ba-runtime-auth-keycloak.md)

# 使用 Amazon Cognito 配置 Gapwalk OAuth2 身份验证
<a name="ba-runtime-auth-cognito"></a>

本主题介绍如何使用 Amazon Cognito 作为 OAuth2 身份提供者 (IdP)，为 Gapwalk 应用程序配置身份验证。

## 先决条件
<a name="ba-runtime-auth-cognito-prereq"></a>

在本教程中，我们将使用 Amazon Cognito 作为 IdP 和 PlanetDemo 现代化项目。

您可以使用任何其他外部身份提供者。这些 ClientRegistration 信息必须从您的 IdP 处获取，并且是 Gapwalk 身份验证所必需的。有关更多信息，请参阅《[Amazon Cognito 开发人员指南](https://docs.aws.amazon.com/cognito/latest/developerguide/)》。

** ClientRegistration 信息：**

client-id  
 ClientRegistration 的 ID。在我们的示例中，它将是 PlanetsDemo。

client-secret  
您的客户端密钥。

授权端点  
授权服务器的授权端点 URI。

令牌端点  
授权服务器的令牌端点 URI。

jwks 端点  
用于获取 JSON Web 密钥（JWK）的 URI，其中包含用于验证授权服务器颁发的 JSON Web 签名的密钥。

重定向 URI  
授权服务器将最终用户（如果授予了访问权限）重定向到的 URI。

## Amazon Cognito 设置
<a name="cog-setup"></a>

首先，我们将创建和配置一个 Amazon Cognito 用户池和用户，并将其与已部署的 Gapwalk 应用程序用于进行测试。

**注意**  
如果您使用其他 IdP，则可以跳过此步骤。

**创建用户池**

1. 前往中的 Amazon Cognito AWS 管理控制台 并使用您的 AWS 凭证进行身份验证。

1. 选择**用户池**。

1. 选择**创建用户池**。

1. 在**配置登录体验**中，保持 **Cognito 用户池**的默认提供者类型。您可以选择一个或多个 **Cognito 用户池登录选项**；现在，选择**用户名**，然后选择**下一步**。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/cog-auth-provider.png)

1. 在**配置安全要求**中，保留默认设置并通过选择**无 MFA** 来禁用**多重身份验证**，然后选择**下一步**。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/cog-sec-requirements.png)

1. 作为安全措施，请禁用**启用自动注册**，然后选择**下一步**。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/cog-config-sign-up.png)

1. 选择**使用 Cognito 发送电子邮件**，然后选择**下一步**。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/cog-email.png)

1. 在**集成应用程序**中，为您的用户池指定一个名称。在**托管身份验证页面**中，选择**使用 Cognito 托管 UI**。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/cog-domain.png)

1. 为简单起见，在**域**中，选择**使用 Cognito 域**并输入域前缀；例如，`https://planetsdemo`。必须将演示应用程序添加为客户端。

   1. 在**初始应用程序客户端**中，选择**机密客户端**。输入应用程序客户端名称（例如 **planetsdemo**），然后选择**生成客户端密钥**。

   1. 在**支持的回调 URL** 中，输入用户在通过身份验证后要重定向到的 URL。该 URL 必须以 `/login/oauth2/code/cognito` 结尾。例如，对于我们的应用程序和后端 Gapwalk 和 BAC 应用程序：

      ```
      http://localhost:8080/bac
            http://localhost:8080/bac/login/oauth2/code/cognito
            http://localhost:8080/gapwalk-application
            http://localhost:8080/gapwalk-application/login/oauth2/code/cognito
            http://localhost:8080/planetsdemo
            http://localhost:8080/planetsdemo/login/oauth2/code/cognito
      ```

      您可以稍后编辑该 URL。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/cog-urls.png)

   1. 在 “**允许注销”** 中， URLs输入您希望 Amazon Cognito 在应用程序注销用户时重定向到的注销页面的 URL。例如，对于后端 Gapwalk 和 BAC 应用程序：

      ```
      http://localhost:8080/bac/logout
      http://localhost:8080/gapwalk-application/logout
      http://localhost:8080/planetsdemo/logout
      ```

      您可以稍后编辑该 URL。

   1. 在**高级应用程序客户端设置**和**属性读写权限**部分中保留默认值。

   1. 选择**下一步**。

1. 在**检查并创建**中，验证您的选择，然后选择**创建用户池**。

有关更多信息，请参阅[创建用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-create-user-pool.html)。

**创建用户**

鉴于自助注册已禁用，请创建一个 Amazon Cognito 用户。导航到 AWS 管理控制台中的 Amazon Cognito。选择您创建的用户池，然后在**用户**中，选择**创建用户**。

在**用户信息**中，选择**发送电子邮件邀请**，输入用户名和电子邮件地址，然后选择**生成密码**。选择**创建用户**。

**创建角色**

在**群组**选项卡中，创建 3 个群组（SUPER\$1ADMIN、ADMIN 和 USER），并将您的用户关联到其中一个或多个群组。Gapwalk 应用程序稍后会将这些角色映射到 ROLE\$1SUPER\$1ADMIN、ROLE\$1ADMIN 和 ROLE\$1USER，从而可以访问一些受限制的 API REST 调用。

该应用程序实现了与多个 OAuth2 身份提供商配合使用的分层 scope-to-role映射。当使用 Cognito 发行的 JWT 令牌进行资源服务器授权时，令牌中定义的作用域会自动映射到相应的角色。

## 将 Amazon Cognito 集成到 Gapwalk 应用程序中
<a name="integrate-cognito"></a>

在您的 Amazon Cognito 用户池和用户准备就绪后，请访问您的经过现代化改造的应用程序的 `application-main.yml` 文件并添加以下代码：

```
gapwalk-application.security: enabled
gapwalk-application.security.identity: oauth
gapwalk-application.security.issuerUri: https://cognito-idp.<region-id>.amazonaws.com/<pool-id>
gapwalk-application.security.domainName: <your-cognito-domain>

spring:
  security:
    oauth2:
      client:
        registration:
          cognito:
            client-id: <client-id>
            client-name: <client-name>
            client-secret: <client-secret>
            provider: cognito
            authorization-grant-type: authorization_code
            scope: openid
            redirect-uri: "<redirect-uri>"
        provider:
          cognito:
            issuer-uri: ${gapwalk-application.security.issuerUri}
            authorization-uri: ${gapwalk-application.security.domainName}/oauth2/authorize
            jwk-set-uri: ${gapwalk-application.security.issuerUri}/.well-known/jwks.json
            token-uri: ${gapwalk-application.security.domainName}/oauth2/token
            user-name-attribute: username
      resourceserver:
        jwt:
          jwk-set-uri: ${gapwalk-application.security.issuerUri}/.well-known/jwks.json
```

按如下所述替换以下占位符：

1. 前往中的 Amazon Cognito AWS 管理控制台 并使用您的 AWS 凭证进行身份验证。

1. 选择**用户池**，然后选择您创建的用户池。你可以在**用户池 ID *pool-id*** 中找到。

1. 选择**应用程序集成**，在那里你可以找到你的*your-cognito-domain*，然后前往**应用程序客户端和分析**并选择你的应用程序。

1. 在 **App 客户端：YouRapp** 中，你可以找到*client-name**client-id*、和*client-secret*（**显示客户端密钥**）。

1. *region-id*对应于您在其中创建 Amazon Cognito 用户和用户池的 AWS 区域 ID。示例：`eu-west-3`。

1. *redirect-uri*输入您为 “**允许的回传 URL” 指定的 UR** I。在我们的示例中，该 URI 为 `http://localhost:8080/planetsdemo/login/oauth2/code/cognito`。

您可以立即部署 Gapwalk 应用程序，并使用之前创建的用户登录您的应用程序。

# 使用 Keycloak 配置 Gap OAuth2 walk 身份验证
<a name="ba-runtime-auth-keycloak"></a>

本主题介绍如何使用 Keycloak 作为 OAuth2 身份提供者 (IdP) 为 Gapwalk 应用程序配置身份验证。在本教程中，我们使用 Keycloak 24.0.0。

## 先决条件
<a name="ba-runtime-auth-keycloak-prereq"></a>
+ [Keycloak](https://www.keycloak.org/)
+ Gapwalk 应用程序

## Keycloak 设置
<a name="keycloak-setup"></a>

1. 在 Web 浏览器中前往 Keycloak 控制面板。默认凭证为 admin/admin。转到左上角导航栏，创建名称为 **demo** 的领域，如下图所示。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/ba-runtime-auth-keycloak_2.png)

1. 创建名为 **app-demo** 的客户端。  
![\[User interface for creating a new client in an authentication management system.\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/ba-runtime-auth-keycloak_3.jpg)

   将 `localhost:8080` 替换为您的 Gapwalk 应用程序的地址  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/ba-runtime-auth-keycloak_4.png)  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/ba-runtime-auth-keycloak_5.png)

1. 要获取您的客户端密钥，请依次选择**客户端**、**app-demo** 和**凭证**。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/ba-runtime-auth-keycloak_6.jpg)

1. 依次选择**客户端**、**客户端作用域**和**添加预定义映射器**。选择**领域角色**。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/ba-runtime-auth-keycloak_7.jpg)

1. 使用如下图所示的配置编辑您的领域角色。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/ba-runtime-auth-keycloak_8.jpg)

1. 记住已定义的**令牌申领名称**。您需要在 `gapwalk-application.security.claimGroupName` 属性的 Gapwalk 设置定义中使用此值。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/ba-runtime-auth-keycloak_9.jpg)

1. 选择**领域角色**，然后创建 3 个角色：**SUPER\$1ADMIN**、**ADMIN** 和 **USER**。Gapwalk 应用程序稍后会将这些角色映射到 `ROLE_SUPER_ADMIN`、`ROLE_ADMIN` 和 `ROLE_USER`，以便能够访问一些受限制的 API REST 调用。  
![\[alt_text\]](http://docs.aws.amazon.com/zh_cn/m2/latest/userguide/images/ba-runtime-auth-keycloak_10.jpg)

## 将 Keycloak 集成到 Gapwalk 应用程序中
<a name="gapwalk-setup"></a>

按如下方式编辑您的 `application-main.yml`：

```
gapwalk-application.security: enabled
gapwalk-application.security.identity: oauth
gapwalk-application.security.issuerUri: http://<KEYCLOAK_SERVER_HOSTNAME>/realms/<YOUR_REALM_NAME>
gapwalk-application.security.claimGroupName: "keycloak:groups"

gapwalk-application.security.userAttributeName: "preferred_username"
# Use "username" for cognito, 
#     "preferred_username" for keycloak
#      or any other string

spring:
  security:
    oauth2:
      client:
        registration:
          demo:
            client-id: <YOUR_CLIENT_ID>
            client-name: Demo App
            client-secret: <YOUR_CLIENT_SECRET>
            provider: keycloak
            authorization-grant-type: authorization_code
            scope: openid
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
        provider:
          keycloak:
            issuer-uri: ${gapwalk-application.security.issuerUri}
            authorization-uri: ${gapwalk-application.security.issuerUri}/protocol/openid-connect/auth
            jwk-set-uri: ${gapwalk-application.security.issuerUri}/protocol/openid-connect/certs
            token-uri: ${gapwalk-application.security.issuerUri}/protocol/openid-connect/token
            user-name-attribute: ${gapwalk-application.security.userAttributeName}
      resourceserver:
        jwt:
          jwk-set-uri: ${gapwalk-application.security.issuerUri}/protocol/openid-connect/certs
```

将*<KEYCLOAK\$1SERVER\$1HOSTNAME>*、*<YOUR\$1REALM\$1NAME>**<YOUR\$1CLIENT\$1ID>*、和*<YOUR\$1CLIENT\$1SECRET>*，替换为您的 Keycloak 服务器主机名、领域名称、客户端 ID 和客户端密钥。

# 为大型机运行时 AWS 转换配置速率限制
<a name="ba-runtime-rate-limiting"></a>

AWS 大型机运行时转换包括内置的速率限制功能，可保护 gapwalk 应用程序免受过多请求和潜在滥用的侵害。速率限制系统使用 Token Bucket 算法来提供突发容量和持续速率限制。

**Topics**
+ [速率限制概述](#ba-runtime-rate-limiting-overview)
+ [配置属性](#ba-runtime-rate-limiting-config)
+ [启用速率限制](#ba-runtime-rate-limiting-enable)
+ [客户识别](#ba-runtime-rate-limiting-client-id)
+ [速率限制标题](#ba-runtime-rate-limiting-headers)
+ [内存管理](#ba-runtime-rate-limiting-memory)

## 速率限制概述
<a name="ba-runtime-rate-limiting-overview"></a>

速率限制系统提供以下功能：

**代币桶算法**  
+ 允许突发流量，最高可达配置的突发容量
+ 根据每分钟的请求量以稳定的速度充值代币
+ 在不阻塞合法流量峰值的情况下提供流畅的速率限制

**客户识别**  
+ 通过 IP 地址识别客户端，支持代理服务器
+ 支架 X-Forwarded-For和 X-Real-IP标题
+ 处理负载均衡器和反向代理方案

**自动内存管理**  
+ 自动清理过期的速率限制存储桶
+ 可配置的清理间隔和过期时间
+ 防止长时间运行的应用程序出现内存泄漏

**HTTP 集成**  
+ 超过限制时返回 HTTP 429（请求过多）
+ 在响应中包含标准速率限制标题
+ 为客户提供重试后信息

## 配置属性
<a name="ba-runtime-rate-limiting-config"></a>

在`application-main.yaml`文件中配置速率限制：

```
gapwalk:
  ratelimiting:
    enabled: true                                        # Enable/disable rate limiting
    requestsPerMinute: 1000                              # Sustained rate limit per minute
    burstCapacity: 1500                                  # Maximum burst requests allowed
    includeHeaders: true                                 # Include X-RateLimit-* headers
    cleanupIntervalMinutes: 5                            # Cleanup interval for expired buckets
    bucketExpiryHours: 1                                 # Hours after which unused buckets expire
    errorMessage: "Too many requests. Try again later."  # Custom error message
    whitelistIps: ""                                     # Comma-separated IPs to bypass limiting
    perEndpointLimiting: false                           # Apply limits per endpoint (not implemented)
```

### 房产描述
<a name="ba-runtime-rate-limiting-config-properties"></a>

**已启用**  
用于启用或禁用速率限制功能的主开关。默认值：`false`

**requestsPerMinute**  
持续速率限制每分钟允许的请求数。这代表代币充值率。默认值：`1000`

**爆发容量**  
在应用速率限制之前，突发中允许的最大请求数。应高于`requestsPerMinute`以允许流量激增。默认值：`1500`

**包含标题**  
是否在 HTTP 响应中包含标准速率限制标头 (`X-RateLimit-Limit``X-RateLimit-Remaining`,,`X-RateLimit-Reset`)。默认值：`true`

**cleanupIntervalMinutes**  
自动清理过期速率限制存储桶之间的间隔（以分钟为单位）。有助于防止内存泄漏。默认值：`5`

**bucketExpiryHours**  
以小时为单位的时间，在此之后未使用的速率限制存储桶被视为已过期且有资格进行清理。默认值：`1`

**errorMessage**  
超过速率限制时，JSON 响应中返回的自定义错误消息。默认值：`"Too many requests. Try again later."`

**WhitelisTi**  
以逗号分隔的 IP 地址列表，这些地址完全绕过速率限制。对运行状况检查或可信系统很有用。默认值：`empty`

**perEndpointLimiting**  
是否对每个端点应用单独的速率限制，而不是仅对每个客户端应用速率限制。目前尚未实施。默认值：`false`

## 启用速率限制
<a name="ba-runtime-rate-limiting-enable"></a>

要使用默认设置启用速率限制，请执行以下操作：

```
gapwalk:
  ratelimiting:
    enabled: true
```

## 客户识别
<a name="ba-runtime-rate-limiting-client-id"></a>

速率限制系统使用以下优先级顺序识别客户端：

1. **X-Forwarded-For 标头**（如果用逗号分隔，则第一个 IP）

1. **X-Real-IP 标题**

1. 来自 HTTP 请求的@@ **远程地址**

这样可以确保在应用程序落后时正确识别客户端：
+ 负载均衡器
+ 反向代理
+ CDNs
+ API 网关

### 客户识别示例
<a name="ba-runtime-rate-limiting-client-id-example"></a>

```
# Direct connection
Client IP: 192.168.1.100

# Behind load balancer with X-Forwarded-For
X-Forwarded-For: 203.0.113.45, 192.168.1.100
Client IP: 203.0.113.45 (first IP used)

# Behind reverse proxy with X-Real-IP
X-Real-IP: 203.0.113.45
Client IP: 203.0.113.45
```

## 速率限制标题
<a name="ba-runtime-rate-limiting-headers"></a>

启用后`includeHeaders`，以下标头将添加到 HTTP 响应中：

**X-RateLimit-极限**  
客户端的速率限制上限（每分钟请求数）

**X-RateLimit-剩余**  
当前速率限制窗口中剩余的请求数

**X-RateLimit-重置**  
速率限制窗口重置的时间（Unix 时间戳）

### 响应标头示例
<a name="ba-runtime-rate-limiting-headers-example"></a>

```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1640995200
```

### 超出速率限制的响应
<a name="ba-runtime-rate-limiting-headers-exceeded"></a>

当超过速率限制时，系统会返回：

**HTTP 状态**  
429 请求过多

**Content-Type**  
application/json

**Retry-After**  
重试前等待的秒数

```
{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Try again later.",
  "retryAfter": 60,
  "timestamp": 1640995140000
}
```

## 内存管理
<a name="ba-runtime-rate-limiting-memory"></a>

速率限制系统会自动管理内存，以防止长时间运行的应用程序出现泄漏：

**自动清理**  
+ 每`cleanupIntervalMinutes`分钟运行一次
+ 移除长达数小时未使用的`bucketExpiryHours`存储桶
+ 记录清理活动以供监视

**内存效率**  
+ 使用并发数据结构确保线程安全
+ 延迟创建存储桶（仅在需要时创建）
+ 高效的代币桶实现

### 监视清理活动
<a name="ba-runtime-rate-limiting-memory-monitoring"></a>

检查日志中是否有清理消息：

```
INFO  RateLimitingService - Cleaned up 15 expired rate limiting buckets
```