Oracle不直接提供开箱即用的Token认证,但可通过ORDS+PL/SQL+数据库表+JWT库实现;需手动启用OAuth2.0、注册客户端、自建JWT签发与验证逻辑,并确保全链路Header传递、权限、时间同步一致。Oracle本身不直接提供开箱即用的“基于Token的API身份验证”服务,但你可以通过组合使用Oracle REST Data Services(ORDS)、PL/SQL、数据库表和外部JWT库(如APEX_UTIL.ENCODE_JWT或自建签名逻辑)来实现。关键不是“Oracle原生支持”,而是**你如何在ORDS + 数据库层构建可控、可验证、可过期的Token流程**。
ORDS中启用OAuth2.0授权码模式需手动配置
oracle rest data services 22.4+ 支持 oauth2.0 授权码流,但必须显式启用并注册客户端:
- 在 ORDS 管理界面或
ords_params.properties中设置security.oauth2.enabled=true - 调用
ORDS.ENABLE_SCHEMA时需指定p_oauth_enabled => TRUE - 客户端注册信息(
client_id、client_secret)存于USER_OAUTH_CLIENTS视图,不能靠 UI 自动生成,需用ORDS.CREATE_OAUTH_CLIENT过程插入 - 若跳过授权页直接走客户端凭据模式(
grant_type=client_credentials),则必须确保调用方能安全保管client_secret—— 这在前端 SPA 中不可行,仅适用于后端服务间调用
手动生成JWT Token需绕过ORDS内置限制
ORDS 默认不暴露 PL/SQL 函数用于签发 JWT,且其内置的 ORDS.AUTHENTICATE 只处理 Basic Auth 或 Cookie Session。要实现自定义 Token 流程,你得自己写:
- 创建一张
api_tokens表,字段至少含token_hash(SHA-256)、user_id、expires_at、issued_at - 用
DBMS_CRYPTO.HASH+UTL_ENCODE.BASE64_ENCODE手动拼接 JWT Header.Payload.Signature(注意:Oracle 21c+ 才有原生JSON_OBJECT_T支持标准 JWT 结构) - 避免在 PL/SQL 中硬编码密钥;建议将签名密钥存在
DBA_ENCRYPTED_COLUMNS或外部密钥管理器(如 Oracle Key Vault) - 客户端传来的
Authorization: Bearer <token>必须由 ORDS 的pre_hook或自定义模块拦截,再调用验证函数(如is_valid_jwt)查表比对token_hash和有效期
HTTP 401 “Unauthorized” 常见触发点
即使 Token 正确生成,ORDS 层仍可能返回 401,原因往往不在认证逻辑本身,而在请求链路的中间环节:
-
Authorization请求头被反向代理(如 Nginx、Apache)剥离或重写 —— 检查代理配置是否保留该 header:proxy_pass_request_headers on; - ORDS 部署在 WebLogic/Tomcat 上时,Servlet 容器默认不解析
Bearertoken;需在web.xml中添加security-constraint或改用自定义Filter - 数据库用户权限不足:验证函数若查询
api_tokens表,执行用户必须有SELECT权限,且不能依赖DEFINER'S RIGHTS而忽略调用者上下文 - 时间不同步:JWT 的
exp字段校验依赖服务器时间,若 DB 服务器与应用服务器时间偏差 > 30 秒,极易误判过期
Authorization 头丢掉,或把 exp 解成毫秒而非秒,就会卡在 401。


















