I am trying to call Azure Graph API to update the user details, I have verified the access to graph api from my Application in Azure. Below is my code
public async Task<HttpResponseMessage> UpdateUserDetails(string userId, string requestString)
{
if (string.IsNullOrEmpty(userId))
{
throw new ArgumentException("You must spectify a valid user Id", nameof(userId));
}
if(string.IsNullOrWhiteSpace(requestString))
{
return null;
}
var authContext = new AuthenticationContext(AzureAdConfig.Authority);
var getAccessToken = await authContext.AcquireTokenAsync(AzureAdConfig.GraphResourceId, new ClientCredential(AzureAdConfig.AppId, AzureAdConfig.AppKey));
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", getAccessToken.AccessToken);
string url = AzureAdConfig.GraphResourceId + AzureAdConfig.Tenant + "/users/" + userId + "?" + AzureAdConfig.GraphVersion;
HttpRequestMessage request = new HttpRequestMessage(new HttpMethod("PATCH"), url);
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", getAccessToken.AccessToken);
request.Content = new StringContent(requestString, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.SendAsync(request);
return response;
}
Thanks in Advance
According to my test, you can not get HttpResponseMessage with await client.SendAsync(request) in console application. You should use client.SendAsync(request).Result to get HttpResponseMessage. This my code.
static void Main(string[] args)
{
Console.WriteLine( CallWebApiProtected("2778d832-402f-4bc2-aa28-0720c92947d5"));
Console.Read();
}
static HttpResponseMessage CallWebApiProtected(string userId)
{
string authority = "https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/oauth2/token"; //token endpoint https://login.microsoftonline.com/b29343ba-***/oauth2/token
string resourceUri = "https://graph.windows.net/";
string clientId = "6187f317-5f3c-447e-b0c4-1fd7c31ec14e";//your application id
string clientkey = "q6e2d7xPwfa5rWHDCV5Tv/75wVkAnsinAcgF5FFkf7Y=";//your app key
AuthenticationContext authContext = new AuthenticationContext(authority);
ClientCredential clientCredential = new ClientCredential(clientId, clientkey);
AuthenticationResult authenticationResult = authContext.AcquireTokenAsync(resourceUri, clientCredential).Result;
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Specify values for the following required parameters
queryString["api-version"] = "1.6";
// Specify values for path parameters (shown as {...})
var uri = "https://graph.windows.net/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/users/" +userId + "?" + queryString;
Console.WriteLine(uri);
using (var request = new HttpRequestMessage())
{
request.Method = HttpMethod.Get;
request.RequestUri = new Uri(uri);
//request.Content = new StringContent(postBody, Encoding.UTF8, "application/json");
request.Headers.Add("Authorization", "Bearer " + authenticationResult.AccessToken);
HttpResponseMessage response = client.SendAsync(request).Result;
return response;
}
Its result as below.
Besides,you can get HttpResponseMessage with await client.SendAsync(request) in web application. This my code.
public async System.Threading.Tasks.Task<ActionResult> About()
{
HttpResponseMessage response = await CallWebApiProtected("2778d832-402f-4bc2-aa28-0720c92947d5");
ViewBag.Message = response;
return View();
}
static async System.Threading.Tasks.Task<HttpResponseMessage> CallWebApiProtected(string userId)
{
string authority = "https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/oauth2/token"; //token endpoint https://login.microsoftonline.com/b29343ba-***/oauth2/token
string resourceUri = "https://graph.windows.net/";
string clientId = "6187f317-5f3c-447e-b0c4-1fd7c31ec14e";//your application id
string clientkey = "q6e2d7xPwfa5rWHDCV5Tv/75wVkAnsinAcgF5FFkf7Y=";//your app key
AuthenticationContext authContext = new AuthenticationContext(authority);
ClientCredential clientCredential = new ClientCredential(clientId, clientkey);
AuthenticationResult authenticationResult = authContext.AcquireTokenAsync(resourceUri, clientCredential).Result;
Console.WriteLine("--------------------------------");
Console.WriteLine(authenticationResult.AccessToken);
Console.WriteLine("----------------------------");
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Specify values for the following required parameters
queryString["api-version"] = "1.6";
// Specify values for path parameters (shown as {...})
var uri = "https://graph.windows.net/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/users/" + userId + "?" + queryString;
Console.WriteLine(uri);
using (var request = new HttpRequestMessage())
{
request.Method = HttpMethod.Get;
request.RequestUri = new Uri(uri);
//request.Content = new StringContent(postBody, Encoding.UTF8, "application/json");
request.Headers.Add("Authorization", "Bearer " + authenticationResult.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);
return response;
}
}
Its result as below.
Related
I would like to share some bit of experience and troubles that I met while doing a folder creation and moving by using RESTful API.
**Create a Folder: **
You will need sharePoint Token
public async Task<JObject> getSharePointToken()
{
var sharPointTokenRequestUrl = "https://accounts.accesscontrol.windows.net/" + _configuration["MicrosoftGraph: TenantId"] + "/tokens/OAuth/2";
var parameters = new Dictionary<string, string>();
parameters["grant_type"] = "client_credentials";
parameters["client_id"] = "your client id";
parameters["client_secret"] = "your client secret";
parameters["resource"] = "resource id";
var par = new FormUrlEncodedContent(parameters);
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), sharPointTokenRequestUrl))
{
var response = await httpClient.PostAsync(sharPointTokenRequestUrl, par);
string responseBody = await response.Content.ReadAsStringAsync();
var result = JObject.Parse(responseBody);
return result;
}
}
}
Also You will need XRequest Digest
public async Task<JObject> getXRequestDigest()
{
var sharPointXRequestDigesttUrl = "https://your site /_api/contextinfo";
var sharePointTokenString = getSharePointToken().Result.ToString();
var sharePointToken = JsonConvert.DeserializeObject<SharePointTokenDto>(sharePointTokenString);
var parameters = new Dictionary<string, string>();
var par = new FormUrlEncodedContent(parameters);
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + sharePointToken.access_token);
httpClient.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
using (var request = new HttpRequestMessage(new HttpMethod("POST"), sharPointXRequestDigesttUrl))
{
var response = await httpClient.PostAsync(sharPointXRequestDigesttUrl, par);
string responseBody = await response.Content.ReadAsStringAsync();
var result = JObject.Parse(responseBody);
return result;
}
}
}
Then you could Crate Folder In SharePoint
namespace Sharepoint.Dtos
{
public class SharePointTokenDto
{
public string token_type { get; set; }
public string expires_in { get; set; }
public string not_before { get; set; }
public string expires_on { get; set; }
public string resource { get; set; }
public string access_token { get; set; }
}
}
public async Task<Boolean> CrateFolderInSharePoint(string folderPath)
{
var sharePointTokenString = getSharePointToken().Result.ToString();
var sharePointToken = JsonConvert.DeserializeObject<SharePointTokenDto>(sharePointTokenString);
var xRequestDigest = await getXRequestDigest();
var FormDigestValue = xRequestDigest["d"]["GetContextWebInformation"]["FormDigestValue"];
var siteUrl = "https://yoursites-url/sites/SiteName/_api/web/folders";
var folderUrl = "/sites/SiteName/Shared Documents" + folderPath;
var body = new Dictionary<string, string>
{
{ "ServerRelativeUrl", folderUrl }
};
string bodyString = JsonConvert.SerializeObject(body);
bodyString.Insert(0, " \"__metadata\": { \"type\": \"SP.Folder\" } ");
var content = new StringContent(bodyString, Encoding.UTF8, "application/json");
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + sharePointToken.access_token);
httpClient.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
httpClient.DefaultRequestHeaders.Add("X-RequestDigest", FormDigestValue.ToString());
using (var request = new HttpRequestMessage(new HttpMethod("POST"), siteUrl))
{
var response = await httpClient.PostAsync(siteUrl, content);
string responseBody = await response.Content.ReadAsStringAsync();
var result = JObject.Parse(responseBody);
if (response.IsSuccessStatusCode)
{
return true;
}
else
{
return false;
}
}
}
}
I am developing a code to validate openssl keys using NodeJs in AWS Lambda. I have a requirement to fetch the public key from the DynamoDB and to validate with the user given private key. As of now, I have two classes, one is to fetch the data from the dynamodb and second is to validate public key and private. But because of asynchronous NodeJS executing my Second class first and is not waiting until my first class gets the data from dynamoDB.
Please help me to execute the code in sequence.
I have tried Promise, bluebird and callback But I'm not able to understand them
const AWS = require('aws-sdk')
const dynamodb = new AWS.DynamoDB();
var promise = require('promise');
exports.handler = async (event) => {
var privatek = '-----BEGIN RSA PRIVATE KEY-----\n'+
'MIICWwIBAAKBgQC2rWURD7fK/3B0W7d36BJnv4ITzSd+K6o+itgHkqe+0EOvoOn2\n'+
'yHK3J11j2c+BkgAcdfwYaBFhH7Gubvyt0TLAKJvxi6cIbD4DVJqoTwJPzgdCczKZ\n'+
'AdhevoYam3t/Q454pW5N7IoF5IzMgPypRbPhi7JnkqcE1/CIXC3hrysMeQIDAQAB\n'+
'AoGANFPlEIcVGdQkDWC8ZF+Y7hkglLV+q5iscq/pA/pRjMoxqVyJyIRQwABJszGQ\n'+
'TEhbOcveQ8uDtvOSPSpTvSKgy4fxmH0/RuypTYcAD/BN76T1DDODSsyn+KuNOdko\n'+
'x6bo30wexmBL/itya9VJMBM49iMMYtYBtOuoJGamMc+vUQECQQDxaWk9alNa37Yb\n'+
'SAfQRGoU7xJvuVQ8qHBY0EgCzYwaMkWuWKkk8GA058PezUxEjwZN8ZRVsYO2YHG1\n'+
'3w3vcF+ZAkEAwbdf1ZVpPEsVyXeftnnu5uPxjN6SGqojV1M1/QXQJaFVd0SFAWMY\n'+
'LE1tqFI6KEfQ1huehvwXhja6HU5z4p+f4QJAce/xRpYvHx2koj2dynLvqk+nYOmU\n'+
'U0igNZqf0grXC+ocLwwTUKbOkUmtjTNRwq3KKPFStBsi8emU4WST/CUKSQJAE2Af\n'+
'AsLl+rTb4gHIBL1fatKjx14/qNEZpdNZ1AvvzMO9Q6ej0gayVUQNUseer4a3WaL7\n'+
'kS7Hv5HbvbCqIKGsoQJAS3LAPW5Wpc2rHFJQDryIGdVnZLW6YdFXGudzMRjHsIB0\n'+
'UMKUywmjRf45ugQMBKJ+iesDwNLmXtOjcB9AdGRz5w==\n'+
'-----END RSA PRIVATE KEY-----';
var publick = '-----BEGIN PUBLIC KEY-----\n'+
'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2rWURD7fK/3B0W7d36BJnv4IT\n'+
'zSd+K6o+itgHkqe+0EOvoOn2yHK3J11j2c+BkgAcdfwYaBFhH7Gubvyt0TLAKJvx\n'+
'i6cIbD4DVJqoTwJPzgdCczKZAdhevoYam3t/Q454pW5N7IoF5IzMgPypRbPhi7Jn\n'+
'kqcE1/CIXC3hrysMeQIDAQAB\n'+
'-----END PUBLIC KEY-----';
console.log(event["pk"]);
const table = "MARKETPLACE_USER_RELATED_APPS_TABLE";
var dynamo = new Dynamo(table);
var prik = dynamo.read(dynamo.client());
console.log(prik);
var clientid = '12345'; //event['client_id']
var unique_id = parseInt(Math.random()*10000000000000000).toString();
var time_stamp = new Date();
var Authkey = clientid + ':' + unique_id + ':' + time_stamp;
console.log(Authkey+"Authkey");
console.log(time_stamp + 'time_stamp');
var cryp = new CryptoVerify(publick,privatek, Authkey);
console.log(cryp.hash+'hash key');
console.log(event['pk'])
const response = {
statusCode: 200,
body: cryp.verify(cryp.signature())
};
return response
};
function CryptoVerify(publickey, privatekey, authkey)
{
this.crypto = require ('crypto')
this.hash = this.crypto.createHash('sha256')
.update(authkey)
.digest('base64');
console.log(this.hash+'haskkk');
this.signature = function(){
try{
var signer = this.crypto.createSign('sha1');
signer.update(this.hash);
var sign = signer.sign(privatekey,'base64');
console.log(sign + "Sign")
}
catch(e)
{
var sign = "Private key Errpr: Not matching with the Public
key\nExact " +e;
}
return sign;
}
this.verify = function(sign){
var verifier = this.crypto.createVerify('sha1');
verifier.update(this.hash);
try {
this.ver = verifier.verify(publickey, sign,'base64');
console.log(this.ver);
}
catch (e){
console.log("Private key Error: Not matching with the Public
key/n Exact Error:"+e);
this.ver = e
}
return this.ver;
}
}
function Dynamo(table)
{
this.params = {Key :{"email_id":{S:"testuser#tml.com"},
"app_name":{S:"EDH"}},
TableName: table};
this.op = {};
this.client = function(){
try{
var dynamodb = new AWS.DynamoDB();
}
catch(e){
console.log("Error: Class DynamoDB is not defined");
}
return dynamodb;};
this.read = function(dy){
try{
dy.getItem(this.params, function(err, data){
if(err) console.log(err, err.stack);
else {
this.op = data;
console.log(this.op);
}
});
}
catch(e){
console.log('Please check getIten function to clear the error');
}
return this.op;
};
}
I expect result with the dynamoDB value to be fetched first then Validate class.
Use callback version of lambda handler or when using asyc await wrap all the callback into a promise or promisify the methods using Bluebird's promisify all method.
const AWS = require('aws-sdk')
const dynamodb = new AWS.DynamoDB();
var promise = require('promise');
exports.handler = async (event) => {
var privatek = '-----BEGIN RSA PRIVATE KEY-----\n'+
'MIICWwIBAAKBgQC2rWURD7fK/3B0W7d36BJnv4ITzSd+K6o+itgHkqe+0EOvoOn2\n'+
'yHK3J11j2c+BkgAcdfwYaBFhH7Gubvyt0TLAKJvxi6cIbD4DVJqoTwJPzgdCczKZ\n'+
'AdhevoYam3t/Q454pW5N7IoF5IzMgPypRbPhi7JnkqcE1/CIXC3hrysMeQIDAQAB\n'+
'AoGANFPlEIcVGdQkDWC8ZF+Y7hkglLV+q5iscq/pA/pRjMoxqVyJyIRQwABJszGQ\n'+
'TEhbOcveQ8uDtvOSPSpTvSKgy4fxmH0/RuypTYcAD/BN76T1DDODSsyn+KuNOdko\n'+
'x6bo30wexmBL/itya9VJMBM49iMMYtYBtOuoJGamMc+vUQECQQDxaWk9alNa37Yb\n'+
'SAfQRGoU7xJvuVQ8qHBY0EgCzYwaMkWuWKkk8GA058PezUxEjwZN8ZRVsYO2YHG1\n'+
'3w3vcF+ZAkEAwbdf1ZVpPEsVyXeftnnu5uPxjN6SGqojV1M1/QXQJaFVd0SFAWMY\n'+
'LE1tqFI6KEfQ1huehvwXhja6HU5z4p+f4QJAce/xRpYvHx2koj2dynLvqk+nYOmU\n'+
'U0igNZqf0grXC+ocLwwTUKbOkUmtjTNRwq3KKPFStBsi8emU4WST/CUKSQJAE2Af\n'+
'AsLl+rTb4gHIBL1fatKjx14/qNEZpdNZ1AvvzMO9Q6ej0gayVUQNUseer4a3WaL7\n'+
'kS7Hv5HbvbCqIKGsoQJAS3LAPW5Wpc2rHFJQDryIGdVnZLW6YdFXGudzMRjHsIB0\n'+
'UMKUywmjRf45ugQMBKJ+iesDwNLmXtOjcB9AdGRz5w==\n'+
'-----END RSA PRIVATE KEY-----';
var publick = '-----BEGIN PUBLIC KEY-----\n'+
'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2rWURD7fK/3B0W7d36BJnv4IT\n'+
'zSd+K6o+itgHkqe+0EOvoOn2yHK3J11j2c+BkgAcdfwYaBFhH7Gubvyt0TLAKJvx\n'+
'i6cIbD4DVJqoTwJPzgdCczKZAdhevoYam3t/Q454pW5N7IoF5IzMgPypRbPhi7Jn\n'+
'kqcE1/CIXC3hrysMeQIDAQAB\n'+
'-----END PUBLIC KEY-----';
console.log(event["pk"]);
const table = "MARKETPLACE_USER_RELATED_APPS_TABLE";
var dynamo = new Dynamo(table);
var prik = await dynamo.read(dynamo.client());
console.log(prik);
var clientid = '12345'; //event['client_id']
var unique_id = parseInt(Math.random()*10000000000000000).toString();
var time_stamp = new Date();
var Authkey = clientid + ':' + unique_id + ':' + time_stamp;
console.log(Authkey+"Authkey");
console.log(time_stamp + 'time_stamp');
var cryp = new CryptoVerify(publick,privatek, Authkey);
console.log(cryp.hash+'hash key');
console.log(event['pk'])
const response = {
statusCode: 200,
body: cryp.verify(cryp.signature())
};
return response
};
function CryptoVerify(publickey, privatekey, authkey)
{
this.crypto = require ('crypto')
this.hash = this.crypto.createHash('sha256')
.update(authkey)
.digest('base64');
console.log(this.hash+'haskkk');
this.signature = function(){
try{
var signer = this.crypto.createSign('sha1');
signer.update(this.hash);
var sign = signer.sign(privatekey,'base64');
console.log(sign + "Sign")
}
catch(e)
{
var sign = "Private key Errpr: Not matching with the Public
key\nExact " +e;
}
return sign;
}
this.verify = function(sign){
var verifier = this.crypto.createVerify('sha1');
verifier.update(this.hash);
try {
this.ver = verifier.verify(publickey, sign,'base64');
console.log(this.ver);
}
catch (e){
console.log("Private key Error: Not matching with the Public
key/n Exact Error:"+e);
this.ver = e
}
return this.ver;
}
}
function Dynamo(table)
{
this.params = {Key :{"email_id":{S:"testuser#tml.com"},
"app_name":{S:"EDH"}},
TableName: table};
this.op = {};
this.client = function(){
try{
var dynamodb = new AWS.DynamoDB();
}
catch(e){
console.log("Error: Class DynamoDB is not defined");
}
return dynamodb;};
this.read = function(dy){
return new Promise((resolve, reject) => {
try{
dy.getItem(this.params, function(err, data){
if(err) console.log(err, err.stack);
else {
this.op = data;
console.log(this.op);
return resolve(data);
}
});
}
catch(e){
console.log('Please check getIten function to clear the error');
reject('Error')
}
});
//return this.op;
};
}
Thanks all. I have got the solution to the question by searching more on the internet. AWS itself is providing "Promise" method for every service.
I just included promise function as follows:
dynamodb.getItem(params).promise().then(function(data, err){
if(err)
//do something
else
//do something
});
I am new to Nodejs .
I am trying to pass JWT token from Nodejs to java service class.
I am getting JWT token in a variable in Nodejs code that I need to pass to spring mvc application service class.
can anyone please help me on this?
And having confusion with how to integrate Nodejs with java if i pass variable from Nodejs to java?
Node code is,
module.exports = {
verifyReq: function (req, res, next) {
if (req.headers.authorization) {
res.setHeader('Content-Type', 'text/html');
res.write('<div id="_mscontent"><script src="URL"></script>');
var notAuthorized = false;
var authorization = req.headers.authorization;
console.log("authorization: " + authorization);
if (authorization) {
req.isAuthorized = true;
}
try {
var decodedJWT = JWT.decode(authorization.split(' ')[1], "", true);
} catch (e) {
notAuthorized = true;
}
else {
req.isAuthorized = false;
res.status(401);
res.end('Not Authorized!');
return;
}
return req.isAuthorized === true;
}
};
Java Code,
public class GetCarAssetValuesService {
private static String output;
private static String token;
private static Asset[] myObjects;
public void getAssets(String tokenToPass)
throws JsonParseException, JsonMappingException, IOException, JSONException {
System.out.println("In service");
HttpsURLConnection myURLConnection = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
StringBuilder strBuilder = new StringBuilder();
JSONObject jsonObj = new JSONObject(tokenToPass);
System.out.println("success_token= " + jsonObj);
token = jsonObj.getString("access_token");
System.out.println("Print token= " + token);
try {
URL url = new URL(
"Third Party URL");
myURLConnection = (HttpsURLConnection) url.openConnection();
String bearerAuth = "Bearer " + token;
myURLConnection.setRequestProperty("Authorization", bearerAuth);
myURLConnection.setRequestMethod("GET");
myURLConnection.setRequestProperty("Content-Type", "application/json");
myURLConnection.setDoOutput(true);
inputStream = myURLConnection.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
if (myURLConnection.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + myURLConnection.getResponseCode());
}
System.out.println("Here the control cars...");
System.out.println("Output from Server .... \n");
while ((output = bufferedReader.readLine()) != null) {
strBuilder.append(output);
System.out.println(output);
}
myURLConnection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String mindsphereResponse = strBuilder.toString();
System.out.println("Responsesssssss" + mindsphereResponse);
ObjectMapper mapper = new ObjectMapper();
myObjects = mapper.readValue(mindsphereResponse, Asset[].class);
}
Here instead of passing "tokenToPass" i want to get this token from node js i.e.decodeJWT. This "tokenToPass" i am getting from other java service now i want it from Nodejs.
Thanks in Advance..!!!
You can set the JWT token in the HTTP Request header ( nodejs ) and API endpoint ( java ) can be get it from there.
HelloController.java
#Controller
public class HomeController {
#Autowire
private HomeService homeService;
#GetMapping("/hello")
public String home(HttpServletRequest request, Model model) {
helloService.invoke(request.getHeader('JWT_TOKEN_KEY'));
}
}
HelloService.java
#Service
public class HelloService {
public void invoke(jwtToken) {
// Use this jwttoken
}
}
NodeJS.js
var options = {
host: 'your_java_api_endpoint',
port: 80,
path: '/hello',
headers:{
'JWT_TOKEN_KEY':'json web token here'
}
};
http.get(options, function(res) {
res.on("data", function(responseData) {
console.log("data: " + responseData);
});
}).on('error', function(e) {
console.log("http error : " + e);
});
My Authentication code is i thing i might be wrong.
I attached my code please refer
private const string FileDownloadURL =
"https://{0}.blob.core.windows.net/{1}/{2}";
public async Task<string> DownloaDFileToBlob(string blobname, string downloadpath, string filename)
{
string Requesturl = string.Format(FileDownloadURL, storageAccount, blobname, filename);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Requesturl);
string now = DateTime.UtcNow.ToString("R");
string exp = DateTime.UtcNow.AddDays(1).ToString("R");
request.Method = "GET";
request.Headers.Add("x-ms-version", "2015-12-11");
request.Headers.Add("x-ms-date", now);
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add("Authorization", AuthorizationHeader3(now, exp,storageAccount, blobname, filename));
var response = await request.GetResponseAsync();
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
return resp.StatusCode.ToString();
}
}
My Authentication Header add method
private string AuthorizationHeader3(string method, string now, HttpWebRequest request, string storageAccount, string storageKey, string containerName,string filename)
{
string headerResource = $"x-ms-date:{now}\nx-ms-version:2015-12-11";
string canonicalizedResource = $"/{storageAccount}/{containerName}/{filename}\ncomp:metadata\nrestype:container\ntimeout:20";
var contentEncoding = "";
var contentLanguage = "";
var contentLength = "";
var contentMd5 = "";
var contentType = "";
var date = "";
var ifModifiedSince = "";
var ifMatch = "";
var ifNoneMatch = "";
var ifUnmodifiedSince = "";
var range = "";
var stringToSign = $"{method}\n{contentEncoding}\n{contentLanguage}\n{contentLength}\n{contentMd5}\n{contentType}\n{date}\n{ifModifiedSince}\n{ifMatch}\n{ifNoneMatch}\n{ifUnmodifiedSince}\n{range}\n{headerResource}\n{canonicalizedResource}";
var signature = "";
using (var hmacSha256 = new HMACSHA256(Convert.FromBase64String(storageKey)))
{
var dataToHmac = Encoding.UTF8.GetBytes(stringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
return AuthorizationHeader;
}
According to the Get blob API
https://myaccount.blob.core.windows.net/mycontainer/myblob
the canonicalizedResource should be $"/{storageAccount}/{containerName}/{blobName} not
$"/{storageAccount}/{containerName}/{filename}\ncomp:metadata\nrestype:container\ntimeout:20";
Please have a try to use the following demo code to download the blob. It works correctly on my side.
var account = "storageAccount";
var accountKey = "account key";
var container = "container name";
var blobName = "blob name";
var apiVersion = "2015-12-11";
var blobUrl = $"https://{account}.blob.core.windows.net/{container}/{blobName}";
var method = "GET";
var now = DateTime.UtcNow.ToString("R");
var canonicalizedHeaders = $"x-ms-date:{now}\nx-ms-version:{apiVersion }";
var canonicalizedResource = $"/{account}/{container}/{blobName}";
var stringToSign = $"{method}\n\n\n\n\n\n\n\n\n\n\n\n{canonicalizedHeaders}\n{canonicalizedResource}";
var auth = CreateAuthString(account, stringToSign, accountKey);
Uri uri = new Uri(blobUrl);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("x-ms-date", now);
client.DefaultRequestHeaders.Add("x-ms-version", "2015-12-11");
client.DefaultRequestHeaders.Add("Authorization", auth);
HttpResponseMessage response = client.SendAsync(request).Result;
var status = response.IsSuccessStatusCode;
private static string CreateAuthString(string blobStorageAccount, string signStr, string blobStorageAccessKey)
{
string signature;
byte[] unicodeKey = Convert.FromBase64String(blobStorageAccessKey);
using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
{
byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(signStr);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
var authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
blobStorageAccount,
signature);
return authorizationHeader;
}
private static async Task CreateApplication(string tenantId, string
clientId, string redirectUri)
{
var graphUri = new Uri("https://graph.windows.net");
var serviceRoot = new Uri(graphUri, tenantId);
var activeDirectoryClient = new ActiveDirectoryClient(serviceRoot,
async () => AcquireTokenAsyncForUser("https://login.microsoftonline.com/"
+
tenantId, clientId, redirectUri));
var app = new Application
{
Homepage = "https://localhost",
DisplayName = "My Application",
LogoutUrl = "https://localhost",
IdentifierUris = new List<string> {
"https://tenant.onmicrosoft.com/MyApp" },
ReplyUrls = new List<string> { "https://localhost" }
};
await activeDirectoryClient.Applications.AddApplicationAsync(app);
Console.WriteLine(app.ObjectId);
}