从0开始构建一个Oauth2Server服务 3
构建服务器端应用程序
服务器端应用程序是处理 OAuth 服务器时遇到的最常见的应用程序类型。这些应用程序在 Web 服务器上运行,其间应用程序的源代码不向大众开放,因而它们能够维护其客户端机密的机密性。
下图说明了一个典型示例,其间用户与正在与客户端通信的浏览器进行交互。客户端和 API 服务器之间有一个独自的安全通信通道。用户的浏览器从不直接向 API 服务器宣布恳求,一切都先通过客户端。
服务器端应用程序运用authorization_code
授权类型。在此流程中,在用户授权应用程序后,应用程序会收到一个“授权代码”,然后能够用该代码交流拜访令牌。
Authorization Code Grant
授权代码是一个暂时代码,客户端将用它来交流拜访令牌。代码自身是从授权服务器获得的,用户能够在授权服务器上看到客户端恳求的信息,并同意或回绝该恳求。
授权代码流供给了一些优于其他授权类型的好处。当用户授权该应用程序时,他们将被重定向回 URL 中带有暂时代码的应用程序。应用程序将该代码交流为拜访令牌。当应用程序恳求拜访令牌时,能够运用客户端密钥对该恳求进行身份验证,从而下降攻击者阻拦授权代码并自行运用它的危险。这也意味着拜访令牌永久不会对用户或他们的浏览器可见,因而这是将令牌传回应用程序的最安全方式,可下降令牌走漏给其他人的危险。
Web 流程的第一步是向用户恳求授权。这是通过创建授权恳求链接供用户单击来实现的。
授权 URL 一般采用以下格式:
https://authorization-server.com/oauth/authorize
?client_id=a17c21ed
&response_type=code
&state=5ca75bd30
&redirect_uri=https%3A%2F%2Fexample-app.com%2Fauth
&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_id
是client_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_id
和client_secret
. 可是,某些服务通过接受client_id
和client_secret
作为 POST 正文参数来支撑身份验证。查看服务的文档以找出服务的希望,由于 OAuth 2.0 标准将此决定留给服务。
更高档的 OAuth 服务器或许还需求其他形式的客户端身份验证,例如 mTLS 或private_key_jwt
. 有关这些示例,请参阅服务自己的文档。
PKCE 验证者
假如服务支撑 Web 服务器应用程序的 PKCE,则客户端在交流授权代码时也需求包括后续 PKCE 参数。相同,请参阅单页应用程序和移动应用程序以获取运用 PKCE 扩展的完好示例。