跳转至

Writing OAuth2 clients for Foundry(为 Foundry 编写 OAuth2 客户端)

This documentation is intended for Foundry users or administrators who wish to write OAuth2 clients to connect to Foundry. This page provides a description of the OAuth 2.0 Authorization Framework ↗ and details about Foundry’s implementation of OAuth2. Additionally, the Foundry Third-Party Application & API Agreement governs the use of third-party applications on the Foundry platform and should be understood by creators and administrators of third-party applications.

OAuth2 overview

The OAuth2 authorization framework enables third-party applications to obtain controlled access to a service. OAuth2 improves on the traditional client-server authorization model by providing a layer that enables clients (like a third-party application) to request access through the use of a specifically-issued access tokens and refresh tokens, rather than a user’s credentials or static bearer tokens. OAuth2 manages this access through the use of grants, which are methods of obtaining access tokens.

Supporting OAuth2 integration

The following sections describe how to support OAuth2 in a third-party application. Throughout the document, client refers to the third-party application, authorization server refers to Foundry’s authorization server, and user refers to the end-user of the third-party application.

To use OAuth2 with Foundry, you must register your application by following the Registering Third-Party Applications instructions and choose one of the authorization options in the next sub-sections.

Authorization code grant

The authorization code grant allows the client to act on behalf of existing Foundry users. The application must request the set of Foundry permissions they need access to, then a Foundry user must explicitly grant the client access to those permissions on their account. Foundry allows the client to be restricted to a limited set of resources, or to all the resources a user can access.

The authorization code grant works as follows:

  1. The client creates a code_verifier and code_challenge. This is recommended but not required for confidential clients ↗, such as server-based applications, that can safely store a client secret. It is required for public clients, such as native apps, that cannot safely store a client secret.
  2. The code_verifier is a cryptographically random string that contains A-Z, a-z, 0-9, - (hyphen), . (period), _ (underscore), and ~ (tilde), and is 43 to 128 characters long.
  3. The code_challenge is derived by performing the SHA256 of the code_verifier and then converting that to a Base64-URL-encoded value without padding.
  4. The client application should open a browser and send the user to the authorization endpoint URL with the following parameters added as query parameters:
  5. response_type: This should be set to code.
  6. client_id: This should be set to the ID generated when the third-party application was registered in Foundry.
  7. redirect_uri: This tells the authorization server where to redirect the user after the user approves the request. If not specified, it will default to the first redirect URI value in the Third-Party application setting in Foundry.
  8. scope: This defines the permissions requested. Scopes for public APIs are in the API documentation. Add the offline_access scope to get a refresh token. If you want multiple scopes, concatenate the scopes using a space as a delimiter.
  9. state: This is a random string generated by the application that will be passed back to the application as is. The application should check that the value returned matches the original string to prevent CSRF attacks.
  10. code_challenge: If the client created a code_challenge, it should populate this parameter. The authorization server will internally associate the code_challenge parameter with the authorization code it generates.
  11. code_challenge_method: This should be set to S256.
  12. When the user visits the URL, the authorization server presents the user with a prompt similar to the following and the user then can choose to approves the app’s request.

Authorization request

  1. If the request is successful, the authorization server then redirects the user to the redirect URI that was specified along with the following parameters added as query parameters:
  2. code: This is the authorization code that the authorization server generates.
  3. state: This is the same parameter the client passed in the authorization request. The client should check that it matches the original state parameter that was sent in the request.
  4. The client should then exchange the authorization code for an access token by calling the token endpoint. The following parameters should be sent using the application/x-www-form-urlencoded format in the request body:
  5. grant_type: This should be set to authorization_code.
  6. code: The code that was received from the authorization server.
  7. redirect_uri: The absolute URI that the user agent will be redirected to.
  8. client_id: This should be set to the ID generated when the third-party application was registered in Foundry.
  9. code_verifier: If the client generated a code_verifier, it should send it in this request. The authorization server will verify that the code_verifier matches the code_challenge that was sent in the previous request.
  10. The authorization server then responds with an access token which can then be used by the client to access the requested resources such as REST APIs. The response contains the following parameters:
  11. access_token: The token that can be used by the client to access the requested resources.
  12. token_type: The type of the token that was issued.
  13. expires_in: The lifetime in seconds of the access token.
  14. refresh_token: This is returned only if the requested scope included offline_access. This should be used if the client wants to refresh the access token without the user being present to authorize the request. For more information, see Refreshing an access token.

Client credentials grant

The client credentials grant is designed for non-interactive service-user style workflows where actions the client makes are not associated to normal Foundry users. The client does not act on behalf of normal Foundry users.

Client Credentials Grant

Instead, this grant type automatically creates a Foundry service user associated with the client that can then be granted permissions to access Foundry resources. The token obtained by this grant can be used to access resources on behalf of the created service user. The username of the service user account is the same as the client ID of the application.

:::callout{theme="neutral"} By default, the service account does not have access to any resources. A Foundry administrator must assign the desired roles and permissions to the service user account for the client to perform actions in Foundry. :::

The client credentials grant works as follows:

  1. The client calls the token endpoint. The following parameters should be sent using the application/x-www-form-urlencoded format in the request body:
  2. grant_type: This should be set to client_credentials.
  3. client_id: This should be set to the ID generated when the third-party application was registered in Foundry.
  4. client_secret: This should be set to the client secret that was generated when the third-party application was registered in Foundry.
  5. The authorization server then responds back with the following:
  6. access_token: The token that can be used by the client to access the requested resources.
  7. token_type: The type of the token that was issued.
  8. expires_in: The lifetime in seconds of the access token.
  9. The client can then use the access token to access the requested resources.

Refreshing an access token

Access tokens expire after some time and will need to be obtained again. Any client that needs access to the Foundry API when the user is not present will need to refresh the token.

This can be done by following these steps:

  1. The client should follow the steps outlined in Authorization Code Grant and specify offline_access as part of the requested scope parameter.
  2. The client should save the returned refresh_token that was returned in the final step of Authorization Code Grant.
  3. If the access token expires, the client can then refresh the token by calling the token endpoint endpoint using the following parameters:
  4. grant_type: This should be set to refresh_token.
  5. refresh_token: The access token that was obtained previously for the given user.
  6. client_id: This should be set to the ID generated when the third-party application was registered in Foundry.
  7. client_secret: This should be set to the client secret that was generated when the third-party application was registered in Foundry.
  8. The authorization server will then respond with the following:
  9. access_token The token that can be used by the client to access the requested resources.
  10. token_type: The type of the token that was issued.
  11. expires_in: The lifetime in seconds of the access token.
  12. refresh_token: The refresh token that can be used to refresh the access token. Note that Foundry rotates the refresh token each time the previously issued refresh token is used. Make sure you save both the access_token and the refresh_token.

Refresh token rotation

Refresh tokens can be used to obtain new access tokens. Foundry reduces the risk associated with refresh tokens by rotating the refresh tokens each time the previously issued refresh token is used. A reuse detection protection mechanism ensures that if a refresh token is reused after one minute of its initial use, all access tokens created from this grant are invalidated and a new authorization flow is required. A one minute interval of reuse is allowed to account for possible transient errors like network failures. Additionally, inactive refresh tokens over 30 days old are automatically invalidated. These safeguards reduce risk from potentially compromised tokens by ensuring there are no long-lived refresh tokens.

OAuth2 API reference

The following endpoints can be used to obtain OAuth2 tokens.

Authorization endpoint

GET /multipass/api/oauth2/authorize

The authorization endpoint, used by the client to obtain an authorization code.

Query parameters

Parameter name Type Description
response_type String This must be set to code.
client_id String The unique identifier of the client.
redirect_uri String The absolute URI that the user agent will be redirected to. This must match one of the Redirect URIs that was specified in the Control Panel. You can access this URI again by navigating to the Manage Application screen.
scope String The scope of the permissions to be requested. Scopes for public APIs are in the API documentation and should be listed as a space-separated string.
state String (optional) An arbitrary string passed to the server that gets passed back to the client as is. This helps prevent cross-site request forgery.
code_challenge String (optional) The code challenge generated by the client; used with Authorization Code Grant with Proof Key for Code Exchange (PKCE)
code_challenge_method String (optional) This should be set S256 if code_challenge is used.

Redirect query parameters

If the request is successful, the user’s browser is redirected to the redirect URI specified in the Third-Party application settings or in the redirect URI passed in the request. The following query parameters will be present in the redirect request URI:

Parameter name Type Description
code String The authorization code that was generated. This code will expire after 10 minutes.
state String (optional) If the state parameter was present in the authorization request, this will contain that exact value.

Token endpoint

POST /multipass/api/oauth2/token

The token endpoint is used by the client to obtain an access token by presenting its authorization grant or refresh token.

Header parameters

Parameter name Description
Content-Type Must be application/x-www-form-urlencoded.

Request body parameters

Parameter name Type Description
grant_type String Value must be authorization_code, refresh_token, or client_credentials
code String (optional) The authorization code received from the authorization endpoint. This is required if the grant type is authorization_code
refresh_token String (optional) This is required when grant_type is refresh_token. The value should be the refresh_token that was obtained in the original request when the authorization code was obtained.
redirect_uri String (optional/required) The absolute URI that the user agent will be redirected to. This is required if a redirect URI was specified in the Authorization Request.
scope String (optional) The scope of the permissions to be requested. Scopes for public APIs are in the API documentation and should be listed as a space-separated string.
client_id String The unique identifier of the client.
client_secret String (optional) The application's client secret that was issued during application registration. This is required when grant_type is client_credentials.
code_verifier String (optional) The code verifier used for the PKCE request that the application generated before the authorization request.

Response body

The response JSON has the following fields.

Field name type Description
access_token String The credentials used to access resources.
token_type String The type of the token issued.
expires_in String The lifetime in seconds of the access token.
refresh_token String (optional) The credentials used to obtain new access tokens. Foundry rotates refresh_token every time a refresh_token grant is called. Make sure you save both the access_token and the refresh_token.

Endpoint errors

Error response body

If the request fails, the user’s browser will only be redirected if the access request is denied. In all other cases, an HTML error page is returned which includes the fields below.

Field name Type Description
error String The error code as defined in the next section.
error_description String The human-readable description of the error

Error codes

Error code value Description
invalid_request The request was invalid.
unauthorized_client The client is not authorized to request an authorization code.
access_denied The sever denied the request.
unsupported_response_type The provided response type is not supported.
invalid_scope The requested scope is invalid, unknown, or malformed
server_error There was an unexpected server error.

中文翻译


为 Foundry 编写 OAuth2 客户端

本文档面向希望编写 OAuth2 客户端以连接 Foundry 的 Foundry 用户或管理员。本页提供了 OAuth 2.0 授权框架 ↗ 的描述以及 Foundry 实现 OAuth2 的详细信息。此外,Foundry 第三方应用与 API 协议 规定了在 Foundry 平台上使用第三方应用的相关事宜,第三方应用的创建者和管理员应理解该协议。

OAuth2 概述

OAuth2 授权框架使第三方应用能够获得对服务的受控访问。OAuth2 改进了传统的客户端-服务器授权模型,它提供了一个层,使客户端(如第三方应用)能够通过使用专门颁发的访问令牌(access token)和刷新令牌(refresh token)来请求访问,而不是使用用户的凭据或静态持有者令牌(bearer token)。OAuth2 通过使用授权许可(grant)来管理这种访问,授权许可是获取访问令牌的方法。

支持 OAuth2 集成

以下章节描述了如何在第三方应用中支持 OAuth2。在本文档中,客户端(client) 指第三方应用,授权服务器(authorization server) 指 Foundry 的授权服务器,用户(user) 指第三方应用的最终用户。

要使用 OAuth2 与 Foundry 集成,您必须按照注册第三方应用 的说明注册您的应用,并选择下一小节中的一种授权选项。

授权码许可(Authorization code grant)

授权码许可允许客户端代表现有的 Foundry 用户执行操作。应用必须请求其需要访问的一组 Foundry 权限,然后 Foundry 用户必须明确授予客户端在其账户上访问这些权限的权限。Foundry 允许将客户端限制为访问有限的资源集,或用户可访问的所有资源。

授权码许可的工作流程如下:

  1. 客户端创建一个 code_verifiercode_challenge。对于能够安全存储客户端密钥(client secret)的 机密客户端(confidential clients)↗(例如基于服务器的应用),这是推荐但非必需的。对于无法安全存储客户端密钥的 公共客户端(public clients)(例如原生应用),这是必需的。
    • code_verifier 是一个加密随机字符串,包含 A-Z、a-z、0-9、-(连字符)、.(句点)、_(下划线)和 ~(波浪号),长度为 43 到 128 个字符。
    • code_challenge 是通过对 code_verifier 执行 SHA256 哈希,然后将其转换为无填充的 Base64-URL 编码值而得到的。
  2. 客户端应用应打开一个浏览器,并将用户引导至授权端点(authorization endpoint) URL,并将以下参数作为查询参数添加:
    • response_type:应设置为 code
    • client_id:应设置为在 Foundry 中注册第三方应用时生成的 ID。
    • redirect_uri:告知授权服务器在用户批准请求后将用户重定向到哪里。如果未指定,将默认为 Foundry 中第三方应用设置中的第一个重定向 URI 值。
    • scope:定义请求的权限。公共 API 的作用域(scope)在 API 文档 中。添加 offline_access 作用域以获取刷新令牌。如果需要多个作用域,请使用空格作为分隔符连接它们。
    • state:由应用生成的随机字符串,将原样传递回应用。应用应检查返回的值是否与原始字符串匹配,以防止 CSRF 攻击。
    • code_challenge:如果客户端创建了 code_challenge,则应填充此参数。授权服务器将在内部将 code_challenge 参数与其生成的授权码关联起来。
    • code_challenge_method:应设置为 S256
  3. 当用户访问该 URL 时,授权服务器会向用户显示类似下图的提示,用户可以选择批准应用的请求。

授权请求

  1. 如果请求成功,授权服务器会将用户重定向到指定的重定向 URI,并附带以下参数作为查询参数:
    • code:这是授权服务器生成的授权码。
    • state:这是客户端在授权请求中传递的相同参数。客户端应检查它是否与请求中发送的原始 state 参数匹配。
  2. 然后,客户端应通过调用令牌端点(token endpoint) 来交换授权码以获取访问令牌。应使用 application/x-www-form-urlencoded 格式在请求体中发送以下参数:
    • grant_type:应设置为 authorization_code
    • code:从授权服务器接收到的授权码。
    • redirect_uri:用户代理将被重定向到的绝对 URI。
    • client_id:应设置为在 Foundry 中注册第三方应用时生成的 ID。
    • code_verifier:如果客户端生成了 code_verifier,则应在此请求中发送它。授权服务器将验证 code_verifier 是否与先前请求中发送的 code_challenge 匹配。
  3. 然后,授权服务器会响应一个访问令牌,客户端可以使用该令牌访问请求的资源,例如 REST API。响应包含以下参数:
    • access_token:客户端可用于访问请求资源的令牌。
    • token_type:已颁发令牌的类型。
    • expires_in:访问令牌的生命周期(以秒为单位)。
    • refresh_token:仅当请求的作用域包含 offline_access 时才返回。如果客户端希望在用户不在场授权请求的情况下刷新访问令牌,则应使用此参数。更多信息,请参阅刷新访问令牌

客户端凭证许可(Client credentials grant)

客户端凭证许可专为非交互式服务用户类型的工作流设计,其中客户端执行的操作不与普通的 Foundry 用户关联。客户端不代表普通的 Foundry 用户执行操作。

客户端凭证许可

相反,此许可类型会自动创建一个与客户端关联的 Foundry 服务用户(service user),然后可以授予该用户访问 Foundry 资源的权限。通过此许可获得的令牌可用于代表创建的服务用户访问资源。服务用户账户的用户名与应用客户端 ID 相同。

:::callout{theme="neutral"} 默认情况下,服务账户无权访问任何资源。Foundry 管理员必须为服务用户账户分配所需的角色和权限,客户端才能在 Foundry 中执行操作。 :::

客户端凭证许可的工作流程如下:

  1. 客户端调用令牌端点。应使用 application/x-www-form-urlencoded 格式在请求体中发送以下参数:
    • grant_type:应设置为 client_credentials
    • client_id:应设置为在 Foundry 中注册第三方应用时生成的 ID。
    • client_secret:应设置为在 Foundry 中注册第三方应用时生成的客户端密钥。
  2. 然后,授权服务器会响应以下内容:
    • access_token:客户端可用于访问请求资源的令牌。
    • token_type:已颁发令牌的类型。
    • expires_in:访问令牌的生命周期(以秒为单位)。
  3. 然后,客户端可以使用访问令牌访问请求的资源。

刷新访问令牌

访问令牌会在一段时间后过期,需要重新获取。任何需要在用户不在场时访问 Foundry API 的客户端都需要刷新令牌。

可以通过以下步骤完成:

  1. 客户端应遵循授权码许可中概述的步骤,并将 offline_access 指定为请求的 scope 参数的一部分。
  2. 客户端应保存授权码许可最后一步中返回的 refresh_token
  3. 如果访问令牌过期,客户端可以通过调用令牌端点 端点来刷新令牌,使用以下参数:
    • grant_type:应设置为 refresh_token
    • refresh_token:先前为给定用户获取的访问令牌。
    • client_id:应设置为在 Foundry 中注册第三方应用时生成的 ID。
    • client_secret:应设置为在 Foundry 中注册第三方应用时生成的客户端密钥。
  4. 然后,授权服务器将响应以下内容:
    • access_token:客户端可用于访问请求资源的令牌。
    • token_type:已颁发令牌的类型。
    • expires_in:访问令牌的生命周期(以秒为单位)。
    • refresh_token:可用于刷新访问令牌的刷新令牌。请注意,每次使用先前颁发的刷新令牌时,Foundry 都会轮换刷新令牌。请确保同时保存 access_tokenrefresh_token

刷新令牌轮换

刷新令牌可用于获取新的访问令牌。Foundry 通过每次使用先前颁发的刷新令牌时轮换刷新令牌来降低与刷新令牌相关的风险。 重用检测保护机制确保,如果在首次使用后一分钟内重用刷新令牌,则从此许可创建的所有访问令牌都将失效,并且需要新的授权流程。 允许一分钟的重用间隔,以应对可能的瞬时错误,例如网络故障。此外,超过 30 天未使用的刷新令牌会自动失效。这些安全措施通过确保不存在长期有效的刷新令牌,降低了潜在令牌泄露的风险。

OAuth2 API 参考

以下端点可用于获取 OAuth2 令牌。

授权端点

GET /multipass/api/oauth2/authorize

授权端点,客户端用于获取授权码。

查询参数

参数名 类型 描述
response_type 字符串 必须设置为 code
client_id 字符串 客户端的唯一标识符。
redirect_uri 字符串 用户代理将被重定向到的绝对 URI。必须与控制面板中指定的重定向 URI 之一匹配。您可以通过导航到管理应用 屏幕再次访问此 URI。
scope 字符串 请求权限的作用域。公共 API 的作用域在 API 文档 中,应列为空格分隔的字符串。
state 字符串(可选) 传递给服务器的任意字符串,将原样传递回客户端。这有助于防止跨站请求伪造。
code_challenge 字符串(可选) 客户端生成的代码挑战(code challenge);与带有代码交换证明密钥(PKCE)的授权码许可一起使用
code_challenge_method 字符串(可选) 如果使用了 code_challenge,则应设置为 S256

重定向查询参数

如果请求成功,用户的浏览器将被重定向到第三方应用设置中指定的重定向 URI,或请求中传递的重定向 URI。重定向请求 URI 中将包含以下查询参数:

参数名 类型 描述
code 字符串 生成的授权码。此代码将在 10 分钟后过期。
state 字符串(可选) 如果授权请求中存在 state 参数,则此参数将包含该确切值。

令牌端点

POST /multipass/api/oauth2/token

令牌端点由客户端用于通过提供其授权许可或刷新令牌来获取访问令牌。

头部参数

参数名 描述
Content-Type 必须为 application/x-www-form-urlencoded

请求体参数

参数名 类型 描述
grant_type 字符串 值必须为 authorization_coderefresh_tokenclient_credentials
code 字符串(可选) 从授权端点接收的授权码。如果授权类型为 authorization_code,则此为必需项。
refresh_token 字符串(可选) grant_typerefresh_token 时此为必需项。该值应为在获取授权码的原始请求中获得的 refresh_token
redirect_uri 字符串(可选/必需) 用户代理将被重定向到的绝对 URI。如果在授权请求中指定了重定向 URI,则此为必需项。
scope 字符串(可选) 请求权限的作用域。公共 API 的作用域在 API 文档 中,应列为空格分隔的字符串。
client_id 字符串 客户端的唯一标识符。
client_secret 字符串(可选) 应用注册时颁发的应用客户端密钥。当 grant_typeclient_credentials 时此为必需项。
code_verifier 字符串(可选) 应用在授权请求之前为 PKCE 请求生成的代码验证器(code verifier)。

响应体

响应 JSON 包含以下字段。

字段名 类型 描述
access_token 字符串 用于访问资源的凭据。
token_type 字符串 已颁发令牌的类型。
expires_in 字符串 访问令牌的生命周期(以秒为单位)。
refresh_token 字符串(可选) 用于获取新访问令牌的凭据。每次调用 refresh_token 许可时,Foundry 都会轮换 refresh_token。请确保同时保存 access_tokenrefresh_token

端点错误

错误响应体

如果请求失败,仅当访问请求被拒绝时,用户的浏览器才会被重定向。在所有其他情况下,将返回一个包含以下字段的 HTML 错误页面。

字段名 类型 描述
error 字符串 下一节中定义的错误代码。
error_description 字符串 人类可读的错误描述

错误代码

错误代码值 描述
invalid_request 请求无效。
unauthorized_client 客户端未被授权请求授权码。
access_denied 服务器拒绝了请求。
unsupported_response_type 提供的响应类型不受支持。
invalid_scope 请求的作用域无效、未知或格式错误
server_error 发生了意外的服务器错误。