跳至內容

驗證

OpenAPI 使用術語「安全機制」來表示驗證和授權機制。OpenAPI 3.0 允許您描述使用以下安全機制保護的 API

請依照上述連結取得特定安全類型的指南,或繼續閱讀以了解如何描述一般安全性。

從 OpenAPI 2.0 的變更

如果您先前使用過 OpenAPI 2.0,以下是變更摘要,可協助您開始使用 OpenAPI 3.0

  • securityDefinitions 已重新命名為 securitySchemes,並移至 components 內。
  • type: basic 已取代為 type: httpscheme: basic
  • 新的 type: http 是所有 HTTP 安全機制的傘形類型,包括基本、Bearer 和其他類型,而 scheme 關鍵字表示機制類型。
  • API 金鑰現在可以透過 in: cookie 傳送。
  • 新增了對 OpenID Connect 探索 (type: openIdConnect) 的支援。
  • OAuth 2 安全機制現在可以定義多個 flows
  • OAuth 2 流程已重新命名以符合 OAuth 2 規格accessCode 現在為 authorizationCode,而 application 現在為 clientCredentials

描述安全性

安全性是使用 securitySchemessecurity 關鍵字描述的。您可以使用 securitySchemes 來定義 API 支援的所有安全機制,然後使用 security 將特定機制套用至整個 API 或個別操作。

步驟 1. 定義 securitySchemes

API 使用的所有安全機制都必須在全域 components/securitySchemes 區段中定義。此區段包含具名的安全機制清單,其中每個機制都可以是 type

安全機制的其他必要屬性取決於 type。以下範例說明如何定義各種安全機制。BasicAuthBearerAuth 名稱和其他名稱是任意名稱,將用於從規格中的其他位置參照這些定義。

1
components:
2
securitySchemes:
3
BasicAuth:
4
type: http
5
scheme: basic
6
7
BearerAuth:
8
type: http
9
scheme: bearer
10
11
ApiKeyAuth:
12
type: apiKey
13
in: header
14
name: X-API-Key
15
16
OpenID:
17
type: openIdConnect
18
openIdConnectUrl: https://example.com/.well-known/openid-configuration
19
20
OAuth2:
21
type: oauth2
22
flows:
23
authorizationCode:
24
authorizationUrl: https://example.com/oauth/authorize
25
tokenUrl: https://example.com/oauth/token
26
scopes:
27
read: Grants read access
28
write: Grants write access
29
admin: Grants access to admin operations

步驟 2. 應用安全性

securitySchemes 區段中定義安全機制之後,您可以分別在根層級或操作層級新增 security 區段,將它們套用至整個 API 或個別操作。當在根層級使用時,security 會將指定的安全機制全域套用至所有 API 操作,除非在操作層級覆寫。在以下範例中,API 呼叫可以使用 API 金鑰或 OAuth 2 進行驗證。ApiKeyAuthOAuth2 名稱是指先前在 securitySchemes 中定義的機制。

1
security:
2
- ApiKeyAuth: []
3
- OAuth2:
4
- read
5
- write
6
# The syntax is:
7
# - scheme name:
8
# - scope 1
9
# - scope 2

對於每個機制,您都指定 API 呼叫所需的安全範圍清單 (請參閱下方)。範圍僅用於 OAuth 2 和 OpenID Connect 探索;其他安全機制則使用空的陣列 [] 來替代。可以在個別操作中覆寫全域 security,以使用不同的驗證類型、不同的 OAuth/OpenID 範圍,或完全不進行驗證

1
paths:
2
/billing_info:
3
get:
4
summary: Gets the account billing info
5
security:
6
- OAuth2: [admin] # Use OAuth with a different scope
7
responses:
8
"200":
9
description: OK
10
"401":
11
description: Not authenticated
12
"403":
13
description: Access token does not have the required scope
14
15
/ping:
16
get:
17
summary: Checks if the server is running
18
security: [] # No security
19
responses:
20
"200":
21
description: Server is up and running
22
default:
23
description: Something is wrong

範圍

OAuth 2 和 OpenID Connect 使用範圍來控制對各種使用者資源的權限。例如,寵物商店的範圍可能包括 read_petswrite_petsread_orderswrite_ordersadmin。在應用 security 時,對應於 OAuth 2 和 OpenID Connect 的項目需要指定特定操作所需的範圍清單 (如果 security 是在操作層級使用) 或所有 API 呼叫所需的範圍清單 (如果 security 是在根層級使用)。

1
security:
2
- OAuth2:
3
- scope1
4
- scope2
5
- OpenId:
6
- scopeA
7
- scopeB
8
- BasicAuth: []
  • 在 OAuth 2 的情況下,security 中使用的範圍必須先前在 securitySchemes 中定義。
  • 在使用 OpenID Connect Discovery 的情況下,可能的 scope 會列在由 openIdConnectUrl 指定的 discovery 端點中。
  • 其他方案(Basic、Bearer、API 金鑰等)不使用 scope,因此它們的 security 條目會指定一個空的陣列 []

不同的操作通常需要不同的 scope,例如讀取、寫入或管理員權限。在這種情況下,您應該將具有 scope 的 security 應用於特定的操作,而不是全局應用。

1
# Instead of this:
2
# security:
3
# - OAuth2:
4
# - read
5
# - write
6
7
# Do this:
8
paths:
9
/users:
10
get:
11
summary: Get a list of users
12
security:
13
- OAuth2: [read] # <------
14
...
15
16
post:
17
summary: Add a user
18
security:
19
- OAuth2: [write] # <------
20
...

使用多種驗證類型

某些 REST API 支援多種驗證類型。security 區段允許您使用邏輯 OR 和 AND 來組合安全性需求,以達到期望的結果。security 使用以下邏輯

1
security: # A OR B
2
- A
3
- B
1
security: # A AND B
2
- A
3
B
1
security: # (A AND B) OR (C AND D)
2
- A
3
B
4
- C
5
D

也就是說,security 是一個雜湊映射的陣列,其中每個雜湊映射包含一個或多個已命名的安全性方案。雜湊映射中的項目使用邏輯 AND 組合,而陣列項目使用邏輯 OR 組合。通過 OR 組合的安全性方案是可選的,在給定的上下文中可以使用任何一種。通過 AND 組合的安全性方案必須在同一個請求中同時使用。在這裡,我們可以選擇使用 Basic 驗證或 API 金鑰。

1
security:
2
- basicAuth: []
3
- apiKey: []

在這裡,API 要求在請求中包含一對 API 金鑰。

1
security:
2
- apiKey1: []
3
apiKey2: []

在這裡,我們可以使用 OAuth 2 或一對 API 金鑰。

1
security:
2
- oauth2: [scope1, scope2]
3
- apiKey1: []
4
apiKey2: []

參考

安全性方案物件

安全性需求物件

沒有找到您要尋找的內容嗎?向社群提問
發現錯誤了嗎?讓我們知道