Calling a REST API using Azure function App - azure

I want to call a REST API using Azure function App. REST API uses basic authentication and does not need any request parameters. The result of this API call need to be saved to ADLS gen2 blob storage. Below is the step 1 of the code where I am trying to call the REST API from function App. When I try to debug the code, response has 403 message. Any help is appreciated
string url = String.Format("my_rest_end_point_url");
HttpClient newClient = new HttpClient();
HttpRequestMessage newRequest = new HttpRequestMessage(HttpMethod.Get, url);
newRequest.Headers.Authorization =
new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "username", "pwd"))));
//Read Server Response
string responseMessage = null;
HttpResponseMessage response = await newClient.SendAsync(newRequest);
log.LogInformation("RESPONSE.", response.IsSuccessStatusCode.ToString());
return new OkObjectResult(responseMessage);

Related

REST Api is not returning expected data

I wrote an Auth API where it should retrieve the details from my user, but I'm getting error 404 instead. All my users are stored in an Azure Storage Account, and I was using the TableClient class to handle with my table. However I am not able to go any further when I started to do this Auth. I spent over one week only on this function, and I got no progress on this, here is my code:
[FunctionName(nameof(Auth))]
public static async Task<IActionResult> Auth(
[HttpTrigger(AuthorizationLevel.Admin, "POST", Route = "auth")] HttpRequest req,
[Table("User", Connection = "AzureWebJobsStorage")] TableClient tdClient,
ILogger log)
{
string url = String.Format("http://localhost:7235/api/");
HttpMessageHandler handler = new HttpClientHandler()
{
};
var httpClient = new HttpClient(handler)
{
BaseAddress = new Uri(url),
Timeout = new TimeSpan(0, 2, 0)
};
httpClient.DefaultRequestHeaders.Add("ContentType", "application/json");
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes("roy.mitchel#somecompany.com:pass1234");
string val = System.Convert.ToBase64String(plainTextBytes);
httpClient.DefaultRequestHeaders.Add("Authorization", "Basic " + val);
HttpResponseMessage response = httpClient.GetAsync(url).Result;
return new OkObjectResult(response);
}
How can auth my user using this class? Iam doing on the right way?
Thanks.
Debugging any API issues by looking at just the code, is (as you have discovered) a horribly painful process.
I'd strongly recommend using a MITM proxy (like burp) to get visibility of exactly what is sent to, and received from the API. By using this approach, it generally becomes really obvious what is wrong.
If you can't use this approach, then enable logging for the raw HTTP request and response, as outlined in this guide.

Unable to post to an external API endpoint from an App Service website in Azure

I am doing an HttpPost to the FedEx tracking API endpoint from the backend of a web app that I am hosting in Azure.
The app works fine on my development machine and can post to the endpoint just fine. But after deploying it to my App service it is no longer able to call the FedEx api to get the required oauth token.
AccessTokenInfo responseObj = new();
using (var client = new HttpClient()) {
client.BaseAddress = new Uri(_fedexConfig.BaseUri);
client.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
var response = new HttpResponseMessage();
var allIputParams = new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("grant_type","client_credentials"),
new KeyValuePair<string, string>("client_id",_fedexConfig.ClientId),
new KeyValuePair<string, string>("client_secret", _fedexConfig.ClientSecret)
};
HttpContent requestParams = new FormUrlEncodedContent(allIputParams);
response = await client.PostAsync(_fedexConfig.TokenUri,requestParams).ConfigureAwait(false);
}
When the call is made the response only returns a 403 error "forbidden".
Is there some additional settings that the AppService needs to have to communicate with an api endpoint outside the Azure environment?

How to recover Call Record information from MS Teams via Graph API

We have a stand alone process which needs to get call record details of completed calls via the Graph API.
We have obtained record IDs via the Azure Dashboard so that we can use them with the following endpoint
GET https://graph.microsoft.com/v1.0/communications/callRecords/{id}
as shown in
https://learn.microsoft.com/en-us/graph/api/callrecords-callrecord-get?view=graph-rest-1.0
The Azure App has been configured for access and has readAll permissions set.
The following code generates a token for access, but when actually trying to read back a call record specified by id, it always returns 404 Not found.
var scopes = new string[] { "https://graph.microsoft.com/.default" };
IConfidentialClientApplication app;
app = ConfidentialClientApplicationBuilder.Create(clientID)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri(authority))
.Build();
var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
string id = "YYYYYYYY-F571-45D9-ABC6-XXXXXXXXXXXX"; // Real ID, but obfuscated for this example
HttpResponseMessage response = await httpClient.GetAsync(new Uri("https://graph.microsoft.com/v1.0/communications/callRecords/" + id));
Can anyone advise what I am missing.
Thanks

How to call an API using time trigger Azure function

I have to write an azure function using a time trigger that will hit an API every weekend and fetch the data from that API and store that data to my Azure SQL database.
So, I am not getting how to call an API from time trigger azure function to fetch data and how to store that data into my azure SQL database.
You can follow this link to get started Azure Function timer trigger.
You have to use HTTPClient to call Api.
static HttpClient client = new HttpClient();
// Update port # in the following line.
client.BaseAddress = new Uri("http://localhost:64195/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
Product product = null;
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
product = await response.Content.ReadAsAsync<Product>();
}
return product;
Note: If you have to call lots of API's/endpoints, you may get port exhaustion error. HttpClientFactory is recommended for that scenario.

Graph API is not working via project code but same URL is working via AD Graph Explorer

I have download a MVC application from Git for AAD graph API. I ran this application but each time i am not getting expected result.
To find the error i run same api using postman and generated token below was the response.
{
"odata.error": {
"code": "Request_ResourceNotFound",
"message": {
"lang": "en",
"value": "Resource not found for the segment 'me'."
}
}
}
I am using below Get URL-
https://graph.windows.net/XXXXX/me?api-version=1.6
Also, to verify is it working with AAD Grapg api explorer. After log in everything is working fine.
Below is my code to call Grapg API-
// Get the access token from the cache
string userObjectID =
ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")
.Value;
string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
//AuthenticationContext authContext = new AuthenticationContext(authority,
// new NaiveSessionCache(userObjectID));
ClientCredential credential = new ClientCredential(clientId, appKey);
AuthenticationContext authContext = new AuthenticationContext(authority, true);
result = await authContext.AcquireTokenAsync(graphResourceId.ToString(), credential);
var Token = result.AccessToken;
//// AcquireTokenSilentAsync
//result = await authContext.AcquireTokenSilentAsync(graphResourceId, credential,
// new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
// Call the Graph API manually and retrieve the user's profile.
string requestUrl = String.Format(
CultureInfo.InvariantCulture,
graphUserUrl,
HttpUtility.UrlEncode(tenantId));
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);
// Return the user's profile in the view.
if (response.IsSuccessStatusCode)
{
string responseString = await response.Content.ReadAsStringAsync();
profile = JsonConvert.DeserializeObject<UserProfile>(responseString);
}
Could you guys please tell me what is the problem with my code. Why it is working on AAD explorer not with Localhost.
To request the me endpoint of Azure AD Graph REST, we need to use the delegate token which represents the sign-in user.
The code above you acquire token using the Client Credential flow is request the access token which represents for the application which doesn't contain the info of sign-in user.
To achieve this in the MVC application, we need to acquire the token after you get the authorization code when users login. Next time, we can acquire the token from the token cache based on the login user.
Here is the code for your reference( code sample from here):
result = await authContext.AcquireTokenSilentAsync(graphResourceId, credential,
new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));

Resources