C# 如何对documentdb存储过程REST调用进行身份验证
编辑:问题是parameters.ToString()。正如刘冷宁指出的,您需要添加“/sprocs/sprocname” 我正在尝试在Azure DocumentDB中执行一个存储过程,并在ASP.NET Core 1.0/C#中使用REST调用 我使用此MSDN页面上的方法生成哈希: 我得到了401份未经授权的报告。“存储过程”是正确的文档类型,还是必须输入其他类型C# 如何对documentdb存储过程REST调用进行身份验证,c#,asp.net,azure,authentication,azure-cosmosdb,C#,Asp.net,Azure,Authentication,Azure Cosmosdb,编辑:问题是parameters.ToString()。正如刘冷宁指出的,您需要添加“/sprocs/sprocname” 我正在尝试在Azure DocumentDB中执行一个存储过程,并在ASP.NET Core 1.0/C#中使用REST调用 我使用此MSDN页面上的方法生成哈希: 我得到了401份未经授权的报告。“存储过程”是正确的文档类型,还是必须输入其他类型 public class Database { public async Task<HttpResponse
public class Database
{
public async Task<HttpResponseMessage> StoredProcedure(string database, string collection, string storedProcedure, string[] parameters)
{
//https://{databaseaccount}.documents.azure.com/dbs/{db-id}/colls/{coll-id}/sprocs/{sproc-name}
string resourceLink = $"dbs/{database}/colls/{collection}";
var client = Client("POST", resourceLink, "sprocs");
StringContent content = new StringContent(parameters.ToString(), null, "application/query+json");
var uri = new Uri(_endpointUri, $"dbs/{database}/colls/{collection}/sprocs/{storedProcedure}");
HttpResponseMessage response = await client.PostAsync(uri, content);
return response;
}
private HttpClient Client(string verb, string resourceLink, string resourceType)
{
var client = new HttpClient();
var utc_date = DateTime.UtcNow.ToString("r");
client.DefaultRequestHeaders.Add("x-ms-date", utc_date);
client.DefaultRequestHeaders.Add("x-ms-version", "2015-12-16");
client.DefaultRequestHeaders.Add("x-ms-max-item-count", "10000");
var authHeader = GenerateMasterKeyAuthorizationSignature(utc_date, verb, resourceLink, resourceType, _authorizationKey, "master", "1.0");
client.DefaultRequestHeaders.Add("authorization", authHeader);
return client;
}
private static string GenerateMasterKeyAuthorizationSignature(string utc_date, string verb, string resourceId, string resourceType, string key, string keyType, string tokenVersion)
{
var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };
string payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}\n{1}\n{2}\n{3}\n{4}\n",
verb.ToLowerInvariant(),
resourceType.ToLowerInvariant(),
resourceId,
utc_date.ToLowerInvariant(),
""
);
byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
string signature = Convert.ToBase64String(hashPayLoad);
return System.Net.WebUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}",
keyType,
tokenVersion,
signature));
}
}
公共类数据库
{
公共异步任务StoredProcess(字符串数据库、字符串集合、字符串StoredProcess、字符串[]参数)
{
//https://{databaseaccount}.documents.azure.com/dbs/{db id}/colls/{coll id}/sprocs/{sproc name}
字符串resourceLink=$“dbs/{database}/colls/{collection}”;
var client=client(“POST”、resourceLink、“存储过程”);
StringContent=newstringcontent(parameters.ToString(),null,“application/query+json”);
var uri=新uri(_endpointUri,$“dbs/{database}/colls/{collection}/sprocs/{storedProcedure}”);
HttpResponseMessage response=wait client.PostAsync(uri,内容);
返回响应;
}
私有HttpClient客户端(字符串谓词、字符串资源链接、字符串资源类型)
{
var client=新的HttpClient();
var utc_date=DateTime.UtcNow.ToString(“r”);
client.DefaultRequestHeaders.Add(“x-ms-date”,utc\U日期);
client.DefaultRequestHeaders.Add(“x-ms-version”、“2015-12-16”);
client.DefaultRequestHeaders.Add(“x-ms-max-item-count”、“10000”);
var authHeader=GenerateMasterKeyAuthorizationSignature(utc_日期、动词、resourceLink、resourceType、_authorizationKey、“主”、“1.0”);
client.DefaultRequestHeaders.Add(“authorization”,authHeader);
返回客户;
}
私有静态字符串生成器MasterKeyAuthorizationSignature(字符串utc_日期、字符串谓词、字符串资源ID、字符串资源类型、字符串密钥、字符串密钥类型、字符串令牌版本)
{
var hmacSha256=new System.Security.Cryptography.hmacSha256{Key=Convert.FromBase64String(Key)};
字符串负载=string.Format(System.Globalization.CultureInfo.InvariantCulture,“{0}\n{1}\n{2}\n{3}\n{4}\n”,
动词.ToLowerInvariant(),
resourceType.ToLowerInvariant(),
智囊团,
utc_date.ToLowerInvariant(),
""
);
byte[]hashPayLoad=hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
字符串签名=Convert.ToBase64String(hashPayLoad);
返回System.Net.WebUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture),“type={0}&ver={1}&sig={2}”,
键类型,
令牌版本,
签署);;
}
}
似乎在生成auth令牌时,在resourceId部分,您遗漏了“/sprocs/{storedProcedure}”。您已将其包含在uri中,这是正确的
我附上了一个示例powershell脚本,希望它也能帮助您了解如何生成身份验证令牌
Add-Type -AssemblyName System.Web
$accountName = "<db account name>"
$connectionKey = "<secret key>"
$collectionName = "<coll name>"
$databaseName = "<db name>"
Write-host ("Account " + $accountName)
Write-host ("Database " + $databaseName)
Write-host ("Collection " + $collectionName)
function GetKey([System.String]$Verb = '',[System.String]$ResourceId = '',
[System.String]$ResourceType = '',[System.String]$Date = '',[System.String]$masterKey = '') {
$keyBytes = [System.Convert]::FromBase64String($masterKey)
$text = @($Verb.ToLowerInvariant() + "`n" + $ResourceType.ToLowerInvariant() + "`n" + $ResourceId + "`n" + $Date.ToLowerInvariant() + "`n" + "" + "`n")
$body =[Text.Encoding]::UTF8.GetBytes($text)
$hmacsha = new-object -TypeName System.Security.Cryptography.HMACSHA256 -ArgumentList (,$keyBytes)
$hash = $hmacsha.ComputeHash($body)
$signature = [System.Convert]::ToBase64String($hash)
Write-Host($text)
[System.Web.HttpUtility]::UrlEncode($('type=master&ver=1.0&sig=' + $signature))
}
function GetUTDate() {
$date = get-date
$date = $date.ToUniversalTime();
return $date.ToString("r", [System.Globalization.CultureInfo]::InvariantCulture);
}
function GetDatabases() {
$uri = $rootUri + "/dbs"
$hdr = BuildHeaders -resType dbs
$response = Invoke-RestMethod -Uri $uri -Method Get -Headers $hdr
$response.Databases
Write-Host ("Found " + $Response.Databases.Count + " Database(s)")
}
function GetCollections([string]$dbname){
$uri = $rootUri + "/" + $dbname + "/colls"
$headers = BuildHeaders -resType colls -resourceId $dbname
$response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
$response.DocumentCollections
Write-Host ("Found " + $Response.DocumentCollections.Count + " DocumentCollection(s)")
}
function BuildHeaders([string]$action = "get",[string]$resType, [string]$resourceId){
$authz = GetKey -Verb $action -ResourceType $resType -ResourceId $resourceId -Date $apiDate -masterKey $connectionKey
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", $authz)
$headers.Add("x-ms-version", '2015-12-16')
$headers.Add("x-ms-date", $apiDate)
$headers
}
function PostDocument([string]$document, [string]$dbname, [string]$collection){
$collName = "dbs/"+$dbname+"/colls/" + $collection
$headers = BuildHeaders -action Post -resType docs -resourceId $collName
$headers.Add("x-ms-documentdb-is-upsert", "true")
$uri = $rootUri + "/" + $collName + "/docs"
Write-host ("Calling " + $uri)
$response = Invoke-RestMethod $uri -Method Post -Body $json -ContentType 'application/json' -Headers $headers
$response
}
function PostSprocQuery([string]$dbname, [string]$collection){
$sprocName = "dbs/"+$dbname+"/colls/" + $collection + "/sprocs/samplesproc"
$headers = BuildHeaders -action Post -resType sprocs -resourceId $sprocName
$uri = $rootUri + "/" + $sprocName
Write-host ("Calling " + $uri)
write-host $authz
write-host $apiDate
$response = Invoke-RestMethod $uri -Method Post -Body $json -ContentType 'application/json' -Headers $headers
$response
}
$rootUri = "https://" + $accountName + ".documents.azure.com"
write-host ("Root URI is " + $rootUri)
#validate arguments
$apiDate = GetUTDate
$db = GetDatabases | where { $_.id -eq $databaseName }
if ($db -eq $null) {
write-error "Could not find database in account"
return
}
$dbname = "dbs/" + $databaseName
$collection = GetCollections -dbname $dbname | where { $_.id -eq $collectionName }
if($collection -eq $null){
write-error "Could not find collection in database"
return
}
$json = @"
{
"id": "3"
}
"@
PostDocument -document $json -dbname $databaseName -collection $collectionName
$json = @"
[
"samplesproc"
]
"@
PostSprocQuery -document $json -dbname $databaseName -collection $collectionName
添加类型-AssemblyName System.Web
$accountName=“”
$connectionKey=“”
$collectionName=“”
$databaseName=“”
写入主机(“帐户”+$accountName)
写入主机(“数据库”+$databaseName)
写入主机(“集合”+$collectionName)
函数GetKey([System.String]$Verb='',[System.String]$ResourceId='',
[System.String]$ResourceType='',[System.String]$Date='',[System.String]$masterKey=''){
$keyBytes=[System.Convert]::FromBase64String($masterKey)
$text=@($Verb.ToLowerInvariant()+“`n”+$ResourceType.ToLowerInvariant()+“`n”+$ResourceId+“`n”+$Date.ToLowerInvariant()+“`n”+”+“`n”)
$body=[Text.Encoding]::UTF8.GetBytes($Text)
$hmacsha=新对象-TypeName System.Security.Cryptography.HMACSHA256-ArgumentList(,$keyBytes)
$hash=$hmacsha.ComputeHash($body)
$signature=[System.Convert]::ToBase64String($hash)
写入主机($text)
[System.Web.HttpUtility]::UrlEncode($('type=master&ver=1.0&sig='+$signature))
}
函数GetUTDate(){
$date=获取日期
$date=$date.ToUniversalTime();
返回$date.ToString(“r”,[System.Globalization.CultureInfo]::不变量文化);
}
函数GetDatabases(){
$uri=$rootUri+“/dbs”
$hdr=BuildHeaders-重新键入dbs
$response=Invoke RestMethod-Uri$Uri-Method Get-Headers$hdr
$response.Databases
写入主机(“找到”+$Response.Databases.Count+“数据库”)
}
函数GetCollections([string]$dbname){
$uri=$rootUri+“/”+$dbname+“/colls”
$headers=BuildHeaders-resType colls-resourceId$dbname
$response=Invoke RestMethod-Uri$Uri-Method Get-Headers$Headers
$response.DocumentCollections
写入主机(“找到”+$Response.DocumentCollections.Count+“DocumentCollection”)
}
函数BuildHeaders([string]$action=“get”,[string]$resType,[string]$resourceId){
$authz=GetKey-Verb$action-ResourceType$resType-ResourceId$ResourceId-Date$apiDate-masterKey$connectionKey
$headers=newobject“System.Collections.Generic.Dictionary[[String],[String]]”
$headers.Add(“授权”、$authz)
$headers.Add(“x-ms-version”,“2015-12-16”)
$headers.Add(“x-ms-date”,$apiDate)
$headers
}
函数PostDocument([string]$document,[string]$dbname,[string]$collection){
$collName=“dbs/”+$dbname+“/colls/”+$collection
$headers=BuildHeaders-action Post-resType docs-resourceId$collName
$headers.Add(“x-ms-documentdb-is-upsert”,“true”)
$uri=$rootUri+“/”+$collName+“/docs”
写入主机(“调用”+$uri)
$response=Invoke RestMethod$uri-Method Post-Body$json-ContentType'application/json'-Headers$Headers
$respon