azure - 为 cosmos DB 构建散列令牌签名
问题描述
我正在尝试创建散列令牌以在 cosmos db 中创建文档,但我总是得到 405 方法不允许,有人可以验证我提供的以下格式是否正确吗?
url = https://cosmos-test-cache.documents.azure.com/dbs/FamilyDB/colls/FamilyCollection/docs/123456
ResourceLink = /dbs/FamilyDB/colls/FamilyCollection/docs/123456
ResourceType = docs
HTTP verb = POST
Response
{
"code": "MethodNotAllowed",
"message": "RequestHandler.Post"
}
解决方案
如果你观察官方cosmos db rest api,你会发现创建文档的 url 示例是https://{databaseaccount}.documents.azure.com/dbs/{db-id}/colls/{coll-id}/docs
但是,您的网址是
https://cosmos-test-cache.documents.azure.com/dbs/FamilyDB/colls/FamilyCollection/docs/123456
这是获取文档,而不是创建文档。因此,它被标识为Get
请求而不是POST
请求。
然后405 "MethodNotAllowed"
发生错误。
更新:
让我修复它。
如果你使用sdk,你可以设置disableAutomaticIdGeneration属性来避免设置id。它会自动为你生成id。
喜欢:
但是根据其余的api文档,id属性是必需的。ID 字段会在创建文档时自动添加而无需指定 ID 值。
请参考示例 java rest 代码:
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.json.JSONObject;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
public class CreateDocumentRest {
private static final String account = "***";
private static final String key = "***";
public static void main(String args[]) throws Exception {
String urlString = "https://" + account + ".documents.azure.com/dbs/db/colls/coll/docs";
//prepare for the json body
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "A");
jsonObject.put("id", "123");
String jsonStr = jsonObject.toString();
String encoding = "UTF-8";
System.out.println(jsonStr);
byte[] data = jsonStr.getBytes(encoding);
HttpURLConnection conn = (HttpURLConnection) (new URL(urlString)).openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
getFileRequest(conn, data);
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
BufferedReader br = null;
if (conn.getResponseCode() != 200) {
br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
} else {
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
}
System.out.println("Response body : " + br.readLine());
}
public static void getFileRequest(HttpURLConnection request, byte[] data)
throws Exception {
SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";
String stringToSign = "POST".toLowerCase() + "\n"
+ "docs".toLowerCase() + "\n"
+ "dbs/db/colls/coll" + "\n"
+ date.toLowerCase() + "\n"
+ "" + "\n";
System.out.println("stringToSign : " + stringToSign);
String auth = getAuthenticationString(stringToSign);
request.setRequestMethod("POST");
request.setRequestProperty("x-ms-date", date);
request.setRequestProperty("x-ms-version", "2017-02-22");
request.setRequestProperty("Authorization", auth);
request.setRequestProperty("Content-Length", String.valueOf(data.length));
request.setRequestProperty("Content-Type", "application/json");
}
private static String getAuthenticationString(String stringToSign) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(Base64.decode(key), "HmacSHA256"));
String authKey = Base64.encode(mac.doFinal(stringToSign.getBytes("UTF-8")));
System.out.println("authkey:" + authKey);
String auth = "type=master&ver=1.0&sig=" + authKey;
auth = URLEncoder.encode(auth);
System.out.println("authString:" + auth);
return auth;
}
}
根据我的观察,请调整您的ResourceLink
asdbs/FamilyDB/colls/FamilyCollection
和url
ashttps://cosmos-test-cache.documents.azure.com/dbs/FamilyDB/colls/FamilyCollection/docs
推荐阅读
- swiftui - 如何使用 SwiftUI 在 iOS 上获取和显示联系人照片?
- flutter - 任务“processReleaseGoogleService”执行失败找不到与包名称匹配的客户端
- c++ - Adafruit_NeoPixel 对象在数组中使用时出现异常行为
- flutter - 如何在颤动的textformfield边界内显示标签和错误消息?
- php - Twilio 不调用我的 TwiML 指令 url
- sql - Oracle SQL 性能问题 - 如何在找到第一个实例时使查询停止运行并返回
- python - AttributeError:遵循 boto3 快速入门时,模块“botocore”没有属性“会话”
- python - Pandas:如何在索引之间获取行?
- mongodb - mongo db 使用集合中的值进行聚合匹配
- c# - 从字符串中间查找特定文本和对应的电子邮件 ID,并将其存储到数据表或 C# 中的列表中