导读:本期聚焦于小伙伴创作的《如何使用OCI Java SDK为自定义REST请求生成认证签名》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何使用OCI Java SDK为自定义REST请求生成认证签名》有用,将其分享出去将是对创作者最好的鼓励。

在使用OCI Java SDK调用自定义REST请求时,生成符合规范的认证签名是接口鉴权的核心步骤,OCI采用基于请求信息的签名机制验证调用方身份,签名错误会直接导致请求返回401未授权错误。

如何使用OCI Java SDK为自定义REST请求生成认证签名

OCI认证签名的核心组成

OCI的签名由请求的关键信息拼接后通过私钥加密生成,需要包含的核心元素有:

  • 请求方法,比如GET、POST等
  • 请求路径,包含接口的路径和查询参数
  • 请求头中的必要字段,比如host、date、content-type等
  • 请求体的哈希值,如果是GET等无请求体的请求则需要处理为空值的哈希
  • 签名版本和算法标识,OCI当前常用的是1和RSA-SHA256

准备工作

在生成签名前需要先完成以下准备:

  • 在OCI控制台创建用户,获取用户的OCID
  • 创建API密钥对,将公钥上传到OCI用户设置中,保存好私钥文件
  • 获取租户OCID、区域名称等基础配置信息
  • 在项目中引入OCI Java SDK依赖,Maven配置如下:
<dependency>
    <groupId>com.oracle.oci.sdk</groupId>
    <artifactId>oci-java-sdk-common</artifactId>
    <version>3.25.1</version>
</dependency>

使用SDK生成签名的步骤

1. 加载私钥和配置基础信息

首先从私钥文件中加载私钥,同时初始化租户、用户、区域等配置:

import com.oracle.bmc.auth.AuthenticationDetailsProvider;
import com.oracle.bmc.auth.SimpleAuthenticationDetailsProvider;
import com.oracle.bmc.http.ClientConfigurator;
import com.oracle.bmc.http.signing.DefaultRequestSigner;
import com.oracle.bmc.http.signing.RequestSigner;
import com.oracle.bmc.http.signing.SigningStrategy;
import com.oracle.bmc.model.Range;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

public class OciSignDemo {
    // 基础配置信息,替换为实际值
    private static final String TENANT_ID = "ocid1.tenancy.oc1..your_tenant_id";
    private static final String USER_ID = "ocid1.user.oc1..your_user_id";
    private static final String FINGERPRINT = "your_key_fingerprint";
    private static final String REGION = "us-ashburn-1";
    private static final String PRIVATE_KEY_PATH = "/path/to/your/private_key.pem";

    // 加载私钥方法
    private static PrivateKey loadPrivateKey(String path) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
        String keyContent = new String(Files.readAllBytes(Paths.get(path)));
        // 去除PEM格式的头尾标识和换行
        keyContent = keyContent.replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s", "");
        byte[] keyBytes = Base64.getDecoder().decode(keyContent);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }
}

2. 构造待签名的请求信息

需要把自定义REST请求的方法、路径、头信息、请求体等信息整理成SDK要求的格式:

import com.oracle.bmc.http.internal.Entity;
import com.oracle.bmc.http.internal.SdkHttpDetails;
import com.oracle.bmc.http.signing.RequestSigningException;
import com.oracle.bmc.http.signing.SignedRequest;
import com.oracle.bmc.http.signing.internal.DefaultSignedRequest;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

public class OciSignDemo {
    // 前面的代码省略...

    public static void main(String[] args) throws Exception {
        // 加载私钥
        PrivateKey privateKey = loadPrivateKey(PRIVATE_KEY_PATH);

        // 构造认证信息提供者
        AuthenticationDetailsProvider provider = SimpleAuthenticationDetailsProvider.builder()
                .tenantId(TENANT_ID)
                .userId(USER_ID)
                .fingerprint(FINGERPRINT)
                .privateKey(privateKey)
                .region(REGION)
                .build();

        // 自定义REST请求信息
        String requestMethod = "POST";
        String requestUrl = "https://objectstorage.us-ashburn-1.oraclecloud.com/n/your_namespace/b/your_bucket/o/your_object";
        String requestBody = "{\"name\":\"test\"}";
        Map<String, String> requestHeaders = new HashMap<>();
        requestHeaders.put("content-type", "application/json");
        requestHeaders.put("date", "Mon, 01 Jan 2024 00:00:00 GMT");
        requestHeaders.put("host", "objectstorage.us-ashburn-1.oraclecloud.com");

        // 构造请求URI
        URI uri = new URI(requestUrl);
    }
}

3. 生成签名并添加到请求头

使用OCI Java SDK内置的签名工具生成签名,并将签名相关头信息添加到请求中:

import com.oracle.bmc.http.signing.RequestSigner;
import com.oracle.bmc.http.signing.internal.DefaultRequestSigner;

import java.util.List;
import java.util.Map;

public class OciSignDemo {
    // 前面的代码省略...

    public static void main(String[] args) throws Exception {
        // 前面的代码省略...

        // 初始化签名器
        RequestSigner signer = DefaultRequestSigner.builder()
                .authenticationDetailsProvider(provider)
                .signingStrategy(SigningStrategy.STANDARD)
                .build();

        // 构造待签名的请求对象
        SdkHttpDetails httpDetails = new SdkHttpDetails() {
            @Override
            public String getHttpMethod() {
                return requestMethod;
            }

            @Override
            public URI getUri() {
                return uri;
            }

            @Override
            public Map<String, List<String>> getHeaders() {
                Map<String, List<String>> headers = new HashMap<>();
                requestHeaders.forEach((k, v) -> headers.put(k, List.of(v)));
                return headers;
            }

            @Override
            public Entity getEntity() {
                if (requestBody != null && !requestBody.isEmpty()) {
                    return new Entity() {
                        @Override
                        public byte[] getContent() {
                            return requestBody.getBytes();
                        }

                        @Override
                        public long getContentLength() {
                            return requestBody.getBytes().length;
                        }

                        @Override
                        public String getContentType() {
                            return requestHeaders.get("content-type");
                        }
                    };
                }
                return null;
            }
        };

        // 生成签名并获取签名头
        SignedRequest signedRequest = signer.signRequest(httpDetails);
        Map<String, List<String>> signedHeaders = signedRequest.getHeaders();

        // 输出签名后的请求头,用于后续发送请求
        System.out.println("签名后的请求头:");
        signedHeaders.forEach((k, v) -> System.out.println(k + ": " + String.join(",", v)));
    }
}

常见问题排查

如果签名验证失败,可以从以下几个方向排查:

  • 检查私钥是否和上传到OCI的公钥匹配,指纹是否正确
  • 请求头中的date字段格式是否符合RFC1123规范,和实际时间偏差不超过5分钟
  • 请求路径和查询参数是否和签名时使用的完全一致,不要做额外的编码处理
  • 请求体的哈希计算是否正确,无请求体时要使用空字符串的SHA256哈希
  • 签名版本和算法是否和OCI接口要求一致,当前大部分接口使用签名版本1

总结

借助OCI Java SDK生成自定义REST请求认证签名的核心是正确使用SDK内置的签名工具,提前准备好认证所需的基础信息,按照要求构造待签名的请求对象即可。签名生成后可以直接添加到自定义请求的头部,完成接口鉴权。实际使用中可以根据业务需求封装签名生成工具类,提升复用性。

OCI_Java_SDKREST请求认证签名API鉴权修改时间:2026-06-03 16:05:10

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。