从0开始构建一个Oauth2 Server服务 <3> 构建服务器端应用程序

2023-10-16 09:26:43 浏览数 (2)

服务器端应用程序是处理 OAuth 服务器时遇到的最常见的应用程序类型。这些应用程序在 Web 服务器上运行,其中应用程序的源代码不向公众开放,因此它们可以维护其客户端机密的机密性。

下图说明了一个典型示例,其中用户与正在与客户端通信的浏览器进行交互。客户端和 API 服务器之间有一个单独的安全通信通道。用户的浏览器从不直接向 API 服务器发出请求,一切都先通过客户端。

服务器端应用程序使用authorization_code授权类型。在此流程中,在用户授权应用程序后,应用程序会收到一个“授权代码”,然后可以用该代码交换访问令牌。

Authorization Code Grant

授权代码是一个临时代码,客户端将用它来交换访问令牌。代码本身是从授权服务器获得的,用户可以在授权服务器上看到客户端请求的信息,并批准或拒绝该请求。

授权代码流提供了一些优于其他授权类型的好处。当用户授权该应用程序时,他们将被重定向回 URL 中带有临时代码的应用程序。应用程序将该代码交换为访问令牌。当应用程序请求访问令牌时,可以使用客户端密钥对该请求进行身份验证,从而降低Attack者拦截授权代码并自行使用它的风险。这也意味着访问令牌永远不会对用户或他们的浏览器可见,因此这是将令牌传回应用程序的最安全方式,可降低令牌泄露给其他人的风险。

Web 流程的第一步是向用户请求授权。这是通过创建授权请求链接供用户单击来实现的。

授权 URL 通常采用以下格式:

代码语言:javascript复制
https://authorization-server.com/oauth/authorize
?client_id=a17c21ed
&response_type=code
&state=5ca75bd30
&redirect_uri=https://example-app.com/auth
&scope=photos

确切的 URL 端点将由您连接到的服务指定,但参数名称将始终相同。

请注意,您很可能首先需要在服务中注册您的重定向 URL,然后才会被接受。这也意味着您无法根据请求更改重定向 URL。相反,您可以使用state参数来自定义请求。请参阅下面的详细信息。

用户访问授权页面后,服务向用户显示请求的解释,包括应用程序名称、范围等。如果用户单击“批准”,服务器将重定向回应用程序,带有“代码”和您在查询字符串参数中提供的相同“状态”参数。请务必注意,这不是访问令牌。您可以使用授权码做的唯一一件事就是发出获取访问令牌的请求。

OAuth 安全

直到 2019 年,OAuth 2.0 规范只建议对移动和 JavaScript 应用程序使用PKCE扩展。最新的 OAuth Security BCP 现在建议也将 PKCE 用于服务器端应用程序,因为它也提供了一些额外的好处。常见的 OAuth 服务适应这个新建议可能需要一些时间,但是如果您从头开始构建服务器,您绝对应该为所有类型的客户端支持 PKCE。

授权请求参数

以下参数用于发出授权请求。您应该使用以下参数构建一个查询字符串,并将其附加到从其文档中获取的应用程序授权端点。

response_type=code response_type设置为code指示您需要授权代码作为响应。
client_idclient_id您的应用程序的标识符。首次向该服务注册您的应用程序时,您将收到一个 client_id。
redirect_uri(可选)这redirect_uri可能是可选的,具体取决于 API,但强烈建议使用。这是您希望在授权完成后将用户重定向到的 URL。这必须与您之前在服务中注册的重定向 URL 相匹配。
scope (可选)包含一个或多个范围值(以空格分隔)以请求额外级别的访问权限。这些值将取决于特定的服务。
state 该state参数有两个功能。当用户被重定向回您的应用程序时,您作为状态包含的任何值也将包含在重定向中。这使您的应用程序有机会在用户被定向到授权服务器和再次返回之间持久保存数据,例如使用状态参数作为会话密钥。这可能用于指示授权完成后在应用程序中执行的操作,例如,指示在授权后重定向到您的应用程序的哪些页面。

如果 state 参数包含每个请求的随机值,它也可以用作 CSRF 保护机制。当用户被重定向回您的应用程序时,仔细检查状态值是否与您最初设置的值相匹配。

PKCE

如果服务支持 Web 服务器应用程序的 PKCE,请在此处也包括 PKCE 质询和质询方法。这在单页应用程序和移动应用程序中的完整示例中进行了描述。

将所有这些查询字符串参数组合到授权 URL 中,并将用户的浏览器定向到那里。通常,应用程序会将这些参数放入登录按钮,或者将此 URL 作为来自应用程序自己的登录 URL 的 HTTP 重定向发送。

用户批准请求

用户被带到服务并看到请求后,他们将允许或拒绝该请求。如果他们允许请求,他们将被重定向回指定的重定向 URL 以及查询字符串中的授权代码。然后,应用程序需要将此授权码交换为访问令牌。

交换访问令牌的授权代码

为了交换访问令牌的授权代码,应用程序向服务的令牌端点发出 POST 请求。该请求将具有以下参数。

grant_type(必需的)

grant_type参数必须设置为“authorization_code”。

code(必需的)

此参数用于从授权服务器接收到的授权代码,该代码将包含在该请求的查询字符串参数“code”中。

redirect_uri(可能需要)

如果重定向 URL 包含在初始授权请求中,则它也必须包含在令牌请求中,并且必须相同。有些服务支持注册多个重定向 URL,有些服务需要在每个请求中指定重定向 URL。查看服务的文档以了解详细信息。

客户端身份验证(必需)

该服务将要求客户端在请求访问令牌时对自身进行身份验证。通常,服务支持通过 HTTP Basic Auth 与客户端client_idclient_secret. 但是,某些服务通过接受client_idclient_secret作为 POST 正文参数来支持身份验证。检查服务的文档以找出服务的期望,因为 OAuth 2.0 规范将此决定留给服务。

更高级的 OAuth 服务器可能还需要其他形式的客户端身份验证,例如 mTLS 或private_key_jwt. 有关这些示例,请参阅服务自己的文档。

PKCE 验证者

如果服务支持 Web 服务器应用程序的 PKCE,则客户端在交换授权代码时也需要包含后续 PKCE 参数。同样,请参阅单页应用程序和移动应用程序以获取使用 PKCE 扩展的完整示例。

0 人点赞