私钥JWT流程是比较复杂的OIDC流程之一,需要设置。在Okta,它通常用于获得OAuth4Okta访问令牌,使你能够在你的组织中执行管理任务。
一旦你从这个流程中获得了访问令牌,你就可以把它扔到请求Okta API的授权头中。 但让我们把它分解得更细一些。
步骤1:生成密钥对
通常情况下,人们可能会认为JWTs严格属于身份提供者(IdP)的范畴--在大多数情况下,这是正确的。当IdP向服务提供商(SP)授予令牌时,它是用私人/秘密密钥签署这些令牌。在验证令牌时,SP的部分责任是使用由IdP提供的公钥来验证签名。
私钥JWT流程将其翻转过来--至少在开始时是这样。现在轮到SP生成一个公钥/私钥对,与IdP共享公钥(在步骤2中详述),创建一个JWT,并用他们的私钥签名(在步骤3中详述)。
但我想说的是......步骤1实际上只是生成密钥对。(在这种情况下,RSA密钥的密钥大小为2048位)。
第2步:注册公钥
下一步是在IdP上注册你的公钥。对于Okta来说,这是通过我们的客户端API完成的。通过这一步,Okta将创建一个应用集成,并生成一个唯一的客户端ID - 这个值在创建私钥JWT时将非常重要。这个客户ID以及工作中的公钥解密将验证你的请求。
在其他流程中,如流行的授权码流程,身份提供者会生成一个称为客户秘密的秘密值。在私钥JWT流程中,服务提供者有责任为同样的目的生成一个秘密值--尽管是通过不同的手段。
第3步:获取访问令牌
这一步有两个组成部分(创建私钥JWT,然后将其提交给IdP以获得访问令牌),但Python命令get_access_token.py 一次性执行这两个部分,因此我们可以将其视为一个单一的操作。
使用在步骤1中创建的私钥,你签署了一个具有以下要求的JWT。
'iss': {client ID generated in step 2},
'sub': {client ID generated in step 2},
'aud': {okta_url}/oauth2/v1/token,
"exp": {epoch expiration at future time}
这个令牌被发送到IdP的/token端点。
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
scope={scopes}&
client_id={client ID generated in step 2}&
client_assertion_type=
urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
client_assertion={private key JWT}
假设一切设置正确,IdP应该响应一个访问令牌,你可以用它来访问范围内的资源。
如果想更深入地了解这个流程,你可以查看我们的演练。现在,是时候用Python来设置它了!
Python私钥JWT设置
- 克隆OktaDev私钥 repo,打开终端,
cd,进入项目根目录。 - 用
virtualenv env在根目录下创建一个新的虚拟环境。 - 用
source env/bin/activate来运行虚拟环境。 - 用
pip install -r requirements.txt安装必要的Python软件包。 - 在根文件夹中,创建一个新的
.env文件,并将以下数值粘贴到其中。
PRIVATE_KEY=
PUBLIC_KEY=
MODULUS=
CLIENT_ID=
OKTA_URL=
API_KEY=
SCOPES=
一旦你运行了前两条命令,脚本将为前4个变量生成数值。你将需要填写其他的值。注意: 在Okta创建OAuth客户端时需要API密钥,所以要确保你使用的令牌有创建应用程序的权限。
- OKTA_URL=https://{你的okta_domain}。
- API_KEY={okta_api_key}。
- SCOPES='okta.users.read okta.users.manage'。
SCOPES var是一串授予你最终访问令牌的作用域(用空格隔开),你将使用这些作用域进行管理任务。
运行脚本
要运行这些脚本,请确保你仍然在克隆版本库的根目录下。
步骤1:生成密钥对
在终端运行以下命令。
python generate_keys.py
你应该看到确认信息打印到终端。
///////////////// Keys generated and added to .env file.
当然,你可以跳到.env文件中,看到PRIVATE_KEY,PUBLIC_KEY 和MODULUS 的值在那里被填充。
第2步:在Okta中创建OAuth服务应用
现在你有了密钥对,你可以在Okta中用公钥创建OAuth应用。你在.env文件中定义的作用域也将在应用程序中被授予。在终端键入以下内容。
python create_okta_service_app.py
你将在创建的应用程序的终端中得到确认,应用程序的客户端ID在你的.env文件中被更新,同时也被授予了作用域。
///////////////// Okta Service app created:
{application object}
///////////////// Setting CLIENT_ID in .env:
{client ID of newly created app}
///////////////// Scopes granted:
{scopes granted to the application}
如果你在Okta中导航到你的应用程序,你会看到这个新创建的应用程序,名称为私钥JWT服务应用程序。
第3步:创建PKJ和获取访问令牌
上面的两个脚本只需要运行一次就可以完成设置。从现在开始,你可以运行下面的命令从Okta获得一个访问令牌:
python get_access_token.py
你应该看到访问令牌被打印到终端:
///////////////// Access Token:
{access_token}
你现在可以使用这个令牌,根据你定义的范围,在授权头中以**bearer {access_token}**的形式传递,在你的Okta org上执行管理任务。
总而言之:保持秘密,保持安全
私钥JWT流程的设置很复杂,但一旦这些部分到位,它应该是相当自动化的。一如既往,私钥是城堡的钥匙。