用三个Python命令设置私钥JWT流程

409 阅读5分钟

私钥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设置

  1. 克隆OktaDev私钥 repo,打开终端,cd ,进入项目根目录。
  2. virtualenv env 在根目录下创建一个新的虚拟环境
  3. source env/bin/activate 来运行虚拟环境。
  4. pip install -r requirements.txt 安装必要的Python软件包。
  5. 在根文件夹中,创建一个新的.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_KEYMODULUS 的值在那里被填充。

第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流程的设置很复杂,但一旦这些部分到位,它应该是相当自动化的。一如既往,私钥是城堡的钥匙。