注意:
- 本教程需要访问 Oracle Cloud。要注册免费账户,请参阅开始使用 Oracle Cloud Infrastructure 免费套餐。
- 它对 Oracle Cloud Infrastructure 身份证明、租户和区间使用示例值。完成实验室后,请使用特定于云环境的那些值替换这些值。
使用 OCI IAM 域发布的 JWT 标记访问 ORDS 中的受保护资源
简介
Oracle Cloud Infrastructure Identity and Access Management (OCI IAM) 使用身份域为 OCI 以及 Oracle 和非 Oracle 应用(无论是 SaaS、云托管还是本地部署)提供身份和访问管理功能,例如身份验证、单点登录 (SSO) 和身份生命周期管理。
Oracle REST Data Services (ORDS) 桥接 HTTPS 和 Oracle Database。ORDS 是中间层 Java 应用,它提供数据库管理 REST API、SQL Developer Web、PL/SQL 网关、用于 REST 的简单 Oracle 文档访问 (SODA) 以及发布 RESTful Web 服务以与 Oracle Database 中的数据和存储过程进行交互的功能。
ORDS 发行版 23.3 引入了对 JSON Web Token (JWT) 的支持。通过这些无记名令牌,ORDS 开发人员可以将验证和授权委托给任何符合 OAuth2 的身份提供者 (IdP),以发出 JWT 访问令牌,ORDS 可以通过验证来提供对受 ORDS 保护资源的访问。
在本教程中,我们将演示如何使用 OCI IAM 域发出的 JWT 令牌访问 ORDS 中的受保护资源。在本演示中,我们将使用 OCI 中的 Oracle Autonomous Database,该数据库附带预配置和完全托管的 ORDS 应用。
下图显示了解决方案体系结构的高级表示形式。
目标
- 使用 OCI IAM 域发布的 JWT 令牌访问 ORDS 中的受保护资源。
先决条件
-
OCI 中的用户必须具有必要的策略来管理 Oracle 自治数据库和 OCI IAM 域。有关所有服务的策略参考的更多信息,请参见 Policy Reference 。
-
Oracle Autonomous Database 必须可用。有关详细信息,请参阅预配 Autonomous Database 实例。
-
在 ORDS 接受使用 JWT 的验证和授权之前:
-
必须已设置符合 OAuth2 的 IdP(例如,具有身份域的 OCI IAM Auth0),才能为允许访问 ORDS 资源的用户发出 JWT。
-
如果要将定制声明用于授权策略,必须设置 IdP 以将定制声明添加到其发出的 JWT。
-
-
要使用发布 IdP 提供的相应公共验证密钥验证 JWT,请执行以下操作:
-
签名算法必须为
RS256
、RS384
或RS512
。 -
公共验证密钥必须至少为 2048 位且不能超过 4096 位。
-
公用验证密钥必须以 JSON Web Key (JWK) 格式指定,并且 ORDS 不经过验证即可访问。
-
-
JWK URI 要求:
-
JWK URI 必须可从 ORDS 访问。
-
必须在 JWKS 中存在密钥参数才能验证 JWT 签名。
-
默认情况下,JWKS 的大小最多为 10,000 字节。
-
注: OCI IAM 域及其发出的 JWT 令牌满足上述所有要求。
任务 1:为数据库方案设置 ORDS、定义 API 端点和配置访问控制
-
登录到 OCI 控制台,导航到 Oracle Database ,然后单击 Autonomous Database 。
-
单击 Provisioned Autonomous Database Instance(预配的 Autonomous Database 实例)、 Database Actions(数据库操作),然后单击 SQL 。
-
运行以下查询以确保具有支持 JWT 的 ORDS 版本 23.3 或更高版本。
SELECT * FROM ORDS_METADATA.ORDS_VERSION;
-
运行以下查询以创建用户 (
ordstest
) 并分配所需的权限。CREATE USER ordstest IDENTIFIED BY "<Password>"; GRANT CONNECT, RESOURCE TO ordstest; ALTER USER ordstest DEFAULT ROLE CONNECT, RESOURCE;
-
运行以下查询,为方案启用 ORDS 以允许 REST API 功能。
BEGIN ORDS_ADMIN.ENABLE_SCHEMA( p_enabled => TRUE, p_schema => 'ordstest', p_url_mapping_type => 'BASE_PATH', p_url_mapping_pattern => 'ordstest', p_auto_rest_auth=> FALSE ); commit; END; /
-
运行以下查询,在
ordstest
方案中创建名为emp
的表并插入示例数据。CREATE TABLE ordstest.emp ( EMPNO NUMBER(4,0), ENAME VARCHAR2(10 BYTE), JOB VARCHAR2(9 BYTE), MGR NUMBER(4,0), HIREDATE DATE, SAL NUMBER(7,2), COMM NUMBER(7,2), DEPTNO NUMBER(2,0), CONSTRAINT PK_EMP PRIMARY KEY (EMPNO) );
Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7369,'SMITH','CLERK',7902,to_date('17-DEC-80','DD-MON-RR'),800,null,20); Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7499,'ALLEN','SALESMAN',7698,to_date('20-FEB-81','DD-MON-RR'),1600,300,30); Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7521,'WARD','SALESMAN',7698,to_date('22-FEB-81','DD-MON-RR'),1250,500,30); Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7566,'JONES','MANAGER',7839,to_date('02-APR-81','DD-MON-RR'),2975,null,20); Insert into ordstest.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7654,'MARTIN','SALESMAN',7698,to_date('28-SEP-81','DD-MON-RR'),1250,1400,30);
-
运行以下查询以定义将包含 API 端点的 ORDS 模块 (
demo
)。BEGIN ORDS_ADMIN.DEFINE_MODULE( p_schema => 'ordstest', p_module_name => 'demo', p_base_path => '/demo/', p_items_per_page=> 1000, p_status => 'PUBLISHED', p_comments=> '' ); COMMIT; END; /
-
运行以下查询以定义映射到特定 REST 资源的模板
emp
。BEGIN ORDS_ADMIN.DEFINE_TEMPLATE( p_schema => 'ordstest', p_module_name => 'demo', p_pattern => 'emp', p_priority => 0, p_etag_type => 'HASH', p_comments => '' ); COMMIT; END; /
-
运行以下查询为
emp
创建 GET 请求处理程序,该处理程序运行从表emp
返回数据的简单 SQL 查询。BEGIN ORDS_ADMIN.DEFINE_HANDLER( p_schema => 'ordstest', p_module_name => 'demo', p_pattern => 'emp', p_method => 'GET', p_source_type => ords.source_type_collection_feed, p_source => 'select * from emp', p_items_per_page => 25, p_comments => '' ); COMMIT; END; /
通过将
/ordstest/demo/emp
附加到 Oracle Autonomous Databases 的 ORDS 公共访问 URL(可在工具配置下找到),可以在没有任何验证的情况下查看emp
表。Postman 用在本教程中。 -
运行以下查询以定义保护
demo
模块的特权 (privilegetest
)。DECLARE L_PRIV_ROLES owa.vc_arr; L_PRIV_PATTERNS owa.vc_arr; L_PRIV_MODULES owa.vc_arr; BEGIN L_PRIV_MODULES( 1 ) := 'demo'; ORDS_ADMIN.DEFINE_PRIVILEGE( P_Schema=> 'ordstest', P_PRIVILEGE_NAME => 'privilegetest', P_ROLES => L_PRIV_ROLES, P_PATTERNS => L_PRIV_PATTERNS, P_MODULES => L_PRIV_MODULES, P_LABEL => 'privilegetest', P_DESCRIPTION => 'Demonstrate controlling access with priviliges', P_COMMENTS=> '' ); COMMIT; END; /
由于
demo
模块受privilegetest
特权保护,因此未经适当授权,无法访问该模块。要启用访问,您需要为ordstest
方案创建 JWT 配置文件。这允许 ORDS 验证 JWT bearer 令牌并授予对受保护资源的访问权限,例如演示模块。
任务 2:创建 ORDS JWT 配置文件
可以使用 OAUTH.CREATE_JWT_PROFILE
过程在启用 REST 的方案中创建 JWT 配置文件。但是,每个方案只能定义一个 JWT 概要文件。要更新现有的 JWT 配置文件,必须先将其删除,然后再创建新的 JWT 配置文件。
BEGIN
OAUTH_ADMIN.DELETE_JWT_PROFILE(p_schema=>'ordstest');
OAUTH_ADMIN.CREATE_JWT_PROFILE(
p_schema => 'ordstest',
p_issuer => 'https://idcs-123456789abcdefghijklmnopqrstuvw.identity.oraclecloud.com',
p_audience => 'ords/ordstest/',
p_jwk_url =>'https://idcs-123456789abcdefghijklmnopqrstuvw.identity.oraclecloud.com:443/admin/v1/SigningCert/jwk'
);
COMMIT;
END;
/
此 JWT 概要文件指定发布者、受众和 JWK URL。
p_issuer
必须为非空值,并且必须与 JWT bearer 标记中的iss
声明匹配。p_audience
必须为非空值,并且必须与 JWT bearer 标记中的aud
声明匹配。p_jwk_url
必须是从https://
开始的非空值,并以 JSON Web 密钥 (JWK) 格式标识授权服务器提供的公共验证密钥。
OCI IAM 域的 Issuer
和 JWK URI
可以通过向 OCI IAM 域 URL 发送 GET 请求来获取,附加 /.well-known/openid-configuration
,如下图所示。
要验证 JWT 概要文件配置,请以 ordstest
用户身份登录并运行以下 SQL 查询。
SELECT * FROM ORDS_METADATA.USER_ORDS_JWT_PROFILE;
此查询检索 JWT 概要文件详细信息,确保正确配置了发布者、受众和 JWK URL。
配置 JWT 配置文件后,最终用户可以通过呈现由符合 OAuth 2.0 的 IdP 发出的 JWT 标记(例如 JWT 配置文件中指定的 OCI IAM 域)来访问受 ORDS 保护的资源。成功验证 JWT bearer 令牌后,ORDS 接受以下命令:
-
JWT 受试者声明为进行请求的已验证用户。
-
JWT 范围声明为启用 REST 的方案 ORDS 权限,用户已代表其同意应用程序使用这些权限。
任务 3:启用对 OCI IAM 域签名证书的 ORDS 访问,无需验证
-
转到 OCI 控制台,导航到身份与安全、身份,然后单击域。
-
单击要在其中工作的身份域的名称。您可能需要更改区间以查找所需的域。单击设置和域设置。
-
在访问签名证书部分中,选择配置客户机访问,然后单击保存更改。这允许 ORDS 访问身份域的签名认证,而无需验证。
任务 4:配置资源服务器和客户机、JWT 范围和 ORDS 权限
必须将 IdP 配置为发出 JWT 的范围与所需的 ORDS 权限匹配。如果 ORDS 中的资源受某个权限保护,则必须将该权限名称定义为范围。此范围允许应用程序代表用户请求访问权限。然后,签发的 JWT 必须将范围作为索赔包括在内。由于我们将使用 OCI IAM OAuth2 服务来强制授权,因此我们需要设置一些资源服务器和客户端。
任务 4.1:创建具有所需受众和范围的资源服务器类型的机密应用程序
-
转到正在使用的身份域,然后单击集成应用程序。
-
选择添加应用程序、机密应用程序,然后单击启动工作流。
-
为应用程序输入名称(例如
ORDS-SERVER
),然后单击下一步。 -
在 Resource server configuration(资源服务器配置)部分中,选择 Configure this application as a resource server now 。
-
使用与 JWT 配置文件匹配的主要受众和与 ORDS 特权匹配的范围配置资源服务器。
-
单击下一步和完成。
-
在应用程序概览页中,选择激活并确认要激活应用程序。机密应用程序已激活。
任务 4.2:创建指定所需范围的客户机类型的机密应用程序
-
转到正在使用的身份域,然后单击集成应用程序。
-
选择添加应用程序、机密应用程序,然后单击启动工作流。
-
为应用程序输入名称(例如
ORDS-CLIENT
),然后单击下一步。 -
在客户端配置部分中,选择立即配置此应用程序作为客户端。
-
在授权部分中,选择客户端凭据。
注:在本教程中,我们使用客户端身份证明作为授权类型。您可以根据您的要求选择不同的授权类型,例如面向用户的客户机的授权代码流。
-
在客户机类型中,选择机密。
-
在令牌发布策略部分中,选择特定作为授权资源。
-
单击添加资源,然后在资源下,选择添加范围。为在任务 4.1 中创建的资源服务器选择所需的范围。例如,
privilegetest
。 -
单击下一步和完成。
-
在应用程序概览页中,选择激活并确认要激活应用程序。机密应用程序已激活。
-
复制此客户端应用程序的客户端 ID 和客户端密钥。需要这些身份证明进行验证。
任务 5:使用 JWT Bearer 标记向 ORDS 发送请求
将后期请求(使用 Postman)发送到 OCI IAM 域令牌端点, Grant Type 为 client_credentials
, Scope 为 privilegetest
,如下图中所示。
注:从 OCI IAM 域请求支付方令牌时,受众和范围必须包括在范围字段中。
验证范围、发布者和受众的 JWT 令牌。
现在,可以通过为有效的 JWT bearer 标记提供 get 请求来访问 ordstest
方案中的受保护 ORDS 资源(演示模块),如下图中所示。
ORDS 通过从 JWK URL 检索公钥并验证令牌的签名来验证令牌。如果签名有效,ORDS 将检查 iss
(签发人)和 aud
(受众)索赔是否与 JWT 配置文件中定义的索赔匹配。它还验证作用域声明是否与保护资源的权限相对应。如果满足所有条件,则向用户授予对受保护资源的访问权限。
相关链接
确认
- 作者 — Chaitanya Chintala(云安全顾问)
更多学习资源
浏览 docs.oracle.com/learn 上的其他实验室,或者访问 Oracle Learning YouTube 渠道上的更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 成为 Oracle Learning Explorer。
有关产品文档,请访问 Oracle 帮助中心。
Access Protected Resources in ORDS using a JWT Token Issued by OCI IAM Domains
G28853-01
Copyright ©2025, Oracle and/or its affiliates.