身份验证令牌失败CosmosDB REST API

时间:2018-01-18 14:36:47

标签: c# rest azure azure-cosmosdb

我试图通过REST API从CosmosDB(SQL)获取文档。 使用Azure功能,我根据the code in the documentation确定授权字符串。

我使用以下参数调用此代码:

GenerateAuthToken("GET", "docs", "dbs/vacancies/colls/items/docs", "masterkey", "master", "1.0");

我只想获取数据库 vacancies 和集合 items 中的文档。这些实体存在于CosmosDB中(区分大小写的匹配),并且该集合中有一个文档。

然后我使用postman来调用Cosmos REST API。 我对https://mycosmosdbaccount.documents.azure.com/dbs/vacancies/colls/items/docs进行HTTP GET 头:

x-ms-version : 2017-02-22
Accept: application/json
Authorization: type%3dmaster%26ver%3d1.0%26sig%3dDU1O3I0hMJzF76fedro4M2VnfOhE03aIWgccaVWRBIc%3d
x-ms-date: thu, 18 jan 2018 10:53:23 gmt

我回来了:

{
    "code": "Unauthorized",
    "message": "The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used. Server used the following payload to sign: 'get\ndocs\ndbs/vacancies/colls/items\nthu, 18 jan 2018 14:31:43 gmt\n\n'\r\nActivityId: 637276f1-c4ec-4d5d-8199-022d680b31d2, Microsoft.Azure.Documents.Common/1.19.162.2"
}

我已经尝试了大约一百种不同的resourceLink组合(dbs / vacancies / colls / items / docs)和http get URL,结果总是相同。

请让我知道我做错了什么蠢事。

1 个答案:

答案 0 :(得分:0)

根据您的错误代码,它应该是Request Header授权参数的问题。

我在本地测试了使用java代码获取文档Rest API,它对我有用。

请参阅以下代码:

import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
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 ListDataBaseRest {

    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";
        HttpURLConnection connection = (HttpURLConnection) (new URL(urlString)).openConnection();
        getFileRequest(connection, key);
        connection.connect();


        System.out.println("Response message : " + connection.getResponseMessage());
        System.out.println("Response code : " + connection.getResponseCode());

        BufferedReader br = null;
        if (connection.getResponseCode() != 200) {
            br = new BufferedReader(new InputStreamReader((connection.getErrorStream())));
        } else {
            br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
        }
        System.out.println("Response body : " + br.readLine());
    }

    public static void getFileRequest(HttpURLConnection request, String key)
            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 = "GET".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("GET");
        request.setRequestProperty("x-ms-date", date);
        request.setRequestProperty("x-ms-version", "2017-02-22");
        request.setRequestProperty("Authorization", auth);
        request.setRequestProperty("Content-Type", "application/query+json");

    }

    private static String getAuthenticationString(String stringToSign) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(Base64.decode(key), "HmacSHA256"));
        String authKey = new String(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方法中的GenerateAuthToken参数不正确。

应该是dbs/vacancies/colls/items,而不是dbs/vacancies/colls/items/docs

希望它对你有所帮助。