我必须从3party应用程序访问cosmos DB存储过程,该应用程序仅允许以原始HTTP格式配置和发送请求。
要模拟我使用了提琴手,但是我不知道在拥有模拟器密钥时如何生成正确的授权令牌。
Cosmos DB默认仿真器密钥为C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==
我的原始请求:
POST https://localhost:8081/dbs/Orders/colls/volcano1/sprocs/GetDocumentsAndTransform HTTP/1.1
x-ms-date: Wed, 09 Dec 2015 18:05:07 GMT
Cache-Control: no-cache
authorization: type%3dmaster%26ver%3d1.0%26sig%3dkOU%2bC2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==%3d
User-Agent: contoso/1.0
x-ms-version: 2015-08-06
Accept: application/json
Content-Type: application/json
Host: localhost:8081
Content-Length: 9
Expect: 100-continue
["World"]
失败,出现授权问题。有什么想法可以将密钥转换为HTTPs请求的适当授权值吗?
答案 0 :(得分:2)
您可以看一下Java SDK,它是开源的。 例如。 https://github.com/Azure/azure-cosmosdb-java/blob/master/sdk/src/main/java/com/microsoft/azure/cosmosdb/internal/BaseAuthorizationTokenProvider.java
/**
* This class is used internally by both client (for generating the auth header with master/system key) and by the Gateway when
* verifying the auth header in the Azure Cosmos DB database service.
*/
public class BaseAuthorizationTokenProvider implements AuthorizationTokenProvider {
private final String masterKey;
private final Mac macInstance;
public BaseAuthorizationTokenProvider(String masterKey) {
this.masterKey = masterKey;
byte[] masterKeyDecodedBytes = Utils.Base64Decoder.decode(this.masterKey.getBytes());
SecretKey signingKey = new SecretKeySpec(masterKeyDecodedBytes, "HMACSHA256");
try {
this.macInstance = Mac.getInstance("HMACSHA256");
this.macInstance.init(signingKey);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
throw new IllegalStateException(e);
}
}
/**
* This API is a helper method to create auth header based on client request using masterkey.
*
* @param verb the verb
* @param resourceIdOrFullName the resource id or full name
* @param resourceSegment the resource segment
* @param headers the request headers
* @return the key authorization signature
*/
public String generateKeyAuthorizationSignature(String verb,
String resourceIdOrFullName,
String resourceSegment,
Map<String, String> headers) {
if (verb == null || verb.isEmpty()) {
throw new IllegalArgumentException("verb");
}
if (resourceIdOrFullName == null) {
resourceIdOrFullName = "";
}
if (resourceSegment == null) {
throw new IllegalArgumentException("resourceSegment");
}
if (headers == null) {
throw new IllegalArgumentException("headers");
}
if (this.masterKey == null || this.masterKey.isEmpty()) {
throw new IllegalArgumentException("masterKey");
}
if(!PathsHelper.isNameBased(resourceIdOrFullName)) {
resourceIdOrFullName = resourceIdOrFullName.toLowerCase(Locale.ROOT);
}
// Skipping lower casing of resourceId since it may now contain "ID" of the resource as part of the FullName
String body = String.format("%s\n%s\n%s\n",
verb.toLowerCase(),
resourceSegment,
resourceIdOrFullName);
if (headers.containsKey(HttpConstants.HttpHeaders.X_DATE)) {
body += headers.get(HttpConstants.HttpHeaders.X_DATE).toLowerCase();
}
body += '\n';
if (headers.containsKey(HttpConstants.HttpHeaders.HTTP_DATE)) {
body += headers.get(HttpConstants.HttpHeaders.HTTP_DATE).toLowerCase();
}
body += '\n';
Mac mac = null;
try {
mac = (Mac) this.macInstance.clone();
} catch (CloneNotSupportedException e) {
throw new IllegalStateException(e);
}
byte[] digest = mac.doFinal(body.getBytes());
String auth = Utils.encodeBase64String(digest);
String authtoken = "type=master&ver=1.0&sig=" + auth;
return authtoken;
}