I'm trying to use Azure App Insights API using https://dev.applicationinsights.io/
Got the metrics data using this "https://api.applicationinsights.io/v1/apps/889f31e2-8281-4d8b-bb80-53a9f83d4a09/metrics/requests/duration?interval=PT1H", Passed the api key through headers.
But not able to get the Query:
Tried this:
https://api.applicationinsights.io/v1/apps/889f31e2-8281-4d8b-bb80-53a9f83d4a09/Query/traces | where operation_Id contains 62c5a318-c2cf-434e-a102-0e6efc0a84e7?interval=P7D
Getting Status Code as NotFound.
Any suggestions, Am I missing something?
According to my research, if you want to do query with Azure Application insight rest api, the URL should be like as below
https://api.applicationinsights.io/v1/apps/{appId}/query?query={1}×pan={2}
For example
var client = new HttpClient();
var appId = "";
var query = "traces | where operation_Id contains '33f491236bb412419002b006e1c3058b'";
var timespan = "P7D";
var apiKey=""
string url = string.Format("https://api.applicationinsights.io/v1/apps/{0}/query?query={1}×pan={2}",
appId,
query,
timespan);
var request = new HttpRequestMessage();
request.Method = HttpMethod.Get;
request.Headers.Add("x-api-key", apiKey);
request.RequestUri = new Uri(url);
using (var response = await client.SendAsync(request)) {
var str = await response.Content.ReadAsStringAsync();
Console.WriteLine(JsonConvert.DeserializeObject<JObject>(str));
Console.Read();
}
For more details, please refer to the document. Besides, you also can try the API vai the explorer.
Update
If you want to Azure AD auth to access Azure application insights API, please refer to the following steps
Register Azure AD application in your tenant
Configure API permissions
Create a client secret for the application
Configure assign contributor to the AD application in your Application Insights resource
call the api
// install sdl MSAL.NET to get access token
var client = new HttpClient();
var appId = "";
var query = "traces | where operation_Id contains '33f491236bb412419002b006e1c3058b'";
var timespan = "P7D";
var apiKey=""
string url = string.Format("https://api.applicationinsights.io/v1/apps/{0}/query?query={1}×pan={2}",
appId,
query,
timespan);
string ClientId = "<your ad application clientID>";
string ClientSecret = "<your ad application ClientSecret>";
string tenant = "";
var app = ConfidentialClientApplicationBuilder.Create(ClientId)
.WithClientSecret(ClientSecret)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{tenant}"))
.Build();
string[] scopes = new string[] { "https://api5.applicationinsights.io/.default" };
var result =await app.AcquireTokenForClient(scopes).ExecuteAsync();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
var request = new HttpRequestMessage();
request.Method = HttpMethod.Get;
request.RequestUri = new Uri(url);
using (var response = await client.SendAsync(request)) {
var str = await response.Content.ReadAsStringAsync();
Console.WriteLine(JsonConvert.DeserializeObject<JObject>(str));
Console.Read();
}
For more details, please refer to the document
Related
I'm trying to send a POST request to the following URL using the MS Graph Client.
https://graph.microsoft.com/v1.0/sites/{SiteID}/lists/Documents/contentTypes/addCopyFromContentTypeHub
I looked at the various Request Builders and didn't see anything for "addCopyFromContentTypehub". There's a "ContentTypeAddCopyRequestBuilder", but that's a different action.
I tried getting access to the graph client's HttpProvider, but I can't figure out how to send the authentication with the request.
var requestUrl = graphServiceClient.Sites[siteId].Lists["Documents"].ContentTypes.AppendSegmentToRequestUrl("addCopyFromContentTypeHub");
var contentTypeId = "<ID>";
var body = $"{{\"contentTypeId\": \"{contentTypeId}\"}}";
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, requestUrl))
{
httpRequestMessage.Content = new StringContent(requestUrl, Encoding.UTF8, "application/json");
//Errors here
var result = await graphServiceClient.HttpProvider.SendAsync(httpRequestMessage);
};
There error I get is:
"MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call."
My graph client uses an Azure AD App Registration to make all the calls so I need to include ".WithAppOnly()" on all my requests, but I don't see a way to do that using graphServiceClient.HttpProvider
Any help would be appreciated. Thanks!
You can authenticate HttpRequestMessage through Graph client
await graphServiceClient.AuthenticationProvider.AuthenticateRequestAsync(httpRequestMessage);
Code:
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, requestUrl))
{
httpRequestMessage.Content = new StringContent(requestUrl, Encoding.UTF8, "application/json");
await graphServiceClient.AuthenticationProvider.AuthenticateRequestAsync(httpRequestMessage);
var result = await graphServiceClient.HttpProvider.SendAsync(httpRequestMessage);
};
maybe anyone could help me with RestSharp api automation testing.
I'll try to be as clear as possible.
Basically the scheme is:
I'm sending my username/password credentials & I get BearerToken in return.
I parse the bearer token into a json file.
After I get the bearer token I need to "Authenticate" in order to get the information that I need.
For example i need full company credit report which I get after I input companyName ="Whatever"; companyCode = "Whatever";
{
var client = new RestClient("https://www.myapitesting.com/api/Auth/Authenticate");
var request = new RestRequest(Method.GET);
var body = new AuthenticatePostCredentials { Username = "myUserName", Password = "myPassword" };
request.AddJsonBody(body);
var response = client.Post(request);
HttpStatusCode statusCode = response.StatusCode;
int numericStatusCode = (int)statusCode;
request.AddHeader("content-type", "application/json");
var queryResult = client.Execute<object>(request).Data;
string jsonToken = JsonConvert.SerializeObject(queryResult);
var JSON1 = JToken.Parse(jsonToken);
var pureToken = JSON1.Value<string>("token");
File.WriteAllText(#"C:\Users\....\TestAPI\TestAPI\token.json", pureToken);
Console.WriteLine(pureToken);
Console.WriteLine(numericStatusCode)
The output I get is: token, status code 200 (correct credentials to get the bearertoken)
//////////At this point I get the token and it is writed into my json file/////////////// (the token works)
Now im trying to authenticate with my token and get the company information that I need
var client = new RestClient("https://www.myapitesting.com/api/GetCompanyReport");
var myRequest = new RestRequest(Method.POST);
myRequest.AddHeader("Accept", "application/json");
myRequest.AddHeader("Authorization", $"Bearer{pureToken}");
myRequest.AddHeader("content-type", "application/json");
var companyInfoInput = new AuthenticatePostCredentials { companyName = "MyCompanyName", companyCode = "MyCompanyCode" };
requestas.AddJsonBody(companyInfoInput);
var response = myRequest.Execute(request);
Console.WriteLine(response.Content);
The output I get is error code that says I havent authenticated, even though I pass the bearer token with my addHeader command.
{"ErrorId":401,"ErrorName":"Unauthorized","ErrorDescription":"User is not logged in"}
What am I doing wrong? Any kind of help would be greatly appreciated!
In this case, you could load the "Authenticator" you want to use, in the case of JWT you may instantiate something like this:
var authenticator = new JwtAuthenticator(pureToken);
and then set your client authenticator like this:
client.Authenticator = authenticator;
Mainly, you should not need to set headers by hand for the most commons ones using Restsharp.
You can for example fix this statement:
var myRequest = new RestRequest(url, DataFormat.Json);
var response = client.Post(request);
I also made this gist for you to check an example
If you want to see something more complete I also have this another gist
I want to skip AWS Cognito's Hosted UI for login/authorization. However, when I try to consume the login end point to fetch authorization-code, I'm slapped with MethodNotAllowed response. As per AWS documentation, the login end-point accepts "Get" requests only. Based on my research on this topic, I figured it was possible to use "Post" method with login credentials for the login end point (Thanks to AWS documentation).
Can someone help please me figure out the issue?
AWS Pool Settings:
AWS Pool Settings
C# Code:
I'm using RestSharp as the HTTP client.
private static void CognitoOAuthSignIn(string username, string password)
{
var CLIENT_ID = "<client_id>";
var RESPONSE_TYPE = "code";
var REDIRECT_URI = "https://www.google.com";
var SCOPE = "openid";
var AUTH_DOMAIN = "https://<domain_name>.auth.us-east-1.amazoncognito.com";
var USERNAME = username;
var PASSWORD = password;
RestClient client = null;
// 1. Get XSRF Code
var csrfRequestUrl = $"{AUTH_DOMAIN}/oauth2/authorize?response_type={RESPONSE_TYPE}&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope={SCOPE}";
var csrfRequest = new RestRequest(Method.GET);
client = new RestClient(csrfRequestUrl);
client.CookieContainer = new CookieContainer();
IRestResponse csrfResp = client.Execute(csrfRequest);
var cookie = client.CookieContainer.GetCookieHeader(new Uri(AUTH_DOMAIN));
var code = cookie.Split(';')[0].Substring(11);
// 2. Make login request
var loginRequestUrl = $"{AUTH_DOMAIN}/login?client_id={CLIENT_ID}&response_type={RESPONSE_TYPE}&scope={SCOPE}&redirect_uri={REDIRECT_URI}";
client = new RestClient(loginRequestUrl);
client.DefaultParameters[0].Value = "*/*"; // Setting "Accept" header
client.AddDefaultHeader("Content-Type", "application/x-www-form-urlencoded");
client.AddDefaultHeader("Accept-Encoding", "gzip,deflate");
client.AddDefaultHeader("Accept-Language", "en-US");
client.AddDefaultHeader("Cache-Control", "no-cache");
client.AddDefaultHeader("Cookie", $"csrf-state=; csrf-state-legacy=; XSRF-TOKEN={code}");
var authCodeRequest = new RestRequest(Method.POST);
authCodeRequest.AddParameter("_csrf", code, ParameterType.GetOrPost);
authCodeRequest.AddParameter("username", USERNAME, ParameterType.GetOrPost);
authCodeRequest.AddParameter("password", PASSWORD, ParameterType.GetOrPost);
authCodeRequest.RequestFormat = DataFormat.None;
IRestResponse authCodeResp = client.Execute(authCodeRequest);
Console.WriteLine(authCodeResp.StatusCode); //returns MethodNotAllowed
}
I'm trying to write a web portal that users can use to reset their own Azure AD password. Because of the requirements of my client, the Azure AD SSPR is not an option.
To achieve this I'm using Microsoft Graph. According to the documentation, it is possible to reset a users password using Microsoft Graph if you have User.ReadWrite.All or Directory.AccessAsUser.All permissions.
Then the permissions documentation, the remarks it states that even if you have the Directory.ReadWrite.All permissions you won't be able to reset a users password.
I've done a test to see if this will work but I get an HTTP 403 Forbidden response.
The code I'm using is:
string ResourceUrl = "https://graph.windows.net/";
string AuthorityUrl = "https://login.microsoftonline.com/companyxxx.onmicrosoft.com/oauth2/authorize/";
//Create a user password cradentials.
var credential = new Microsoft.IdentityModel
.Clients
.ActiveDirectory
.UserPasswordCredential("username#xxxx.com", "passwordxxx");
// Authenticate using created credentials
var authenticationContext = new AuthenticationContext(AuthorityUrl);
var authenticationResult = authenticationContext
.AcquireTokenAsync(ResourceUrl, "xxxxxxxx-3017-4833-9923-30d05726b32f", credential)
.Result;
string jwtToken = authenticationResult.AccessToken;
var cred = new Microsoft.Rest
.TokenCredentials(authenticationResult.AccessToken, "Bearer");
HttpClient client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
queryString["api-version"] = "1.6";
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
var uri = "https://graph.windows.net/xxxxxxxx-18fe-xxxx-bb90-d62195600495/users/xxxxxxxx-aa58-4329-xxxx-b39af07325ee?" + queryString;
//var content = new StringContent("{\"passwordProfile\": {\"password\": \"Test123456\", \"forceChangePasswordNextLogin\": true }}");
var response = client.PatchAsync(new Uri(uri), content, jwtToken);
The PatchAsync method is an extension method as below:
public static class HttpClientExtensions
{
public static async Task<HttpResponseMessage> PatchAsync(this HttpClient client,
Uri requestUri, HttpContent iContent, string jwtToken)
{
var method = new HttpMethod("PATCH");
var request = new HttpRequestMessage(method, requestUri)
{
Content = iContent,
};
request.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/json");
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", jwtToken);
HttpResponseMessage response = new HttpResponseMessage();
try
{
response = await client.SendAsync(request);
}
catch (TaskCanceledException e)
{
Console.WriteLine("ERROR: " + e.ToString());
}
return response;
}
}
Could someone please clarify if this is possible using the credentials grant flow with a username and password for authentication. If so how do I achieve this?
You're mixing up Microsoft Graph and Azure AD Graph API. These are two different APIs and calls to one are not interchangeable with the other.
You are correct in that you need to use the Directory.AccessAsUser.All scope for this activity. This scope allows the API to do anything to the AAD that the signed in user would be able to do themselves (i.e. change their own password).
Once you have a valid access_token for the user with Directory.AccessAsUser.All permission, you can update the user's passwordProfile:
PATCH https://graph.microsoft.com/v1.0/me
Content-type: application/json
{
"passwordProfile" : {
"forceChangePasswordNextSignIn": true,
"password": "password-value"
}
}
Is there a simple API using which I can get the size of an ADLS directory? preferably something in C#, but it's not a must.
We could use the Get Content Summary of a Directory REST API to do that.
curl -i "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=GETCONTENTSUMMARY"
C# code demo
var url = "https://tomdatalake.azuredatalakestore.net/webhdfs/v1/tomtest?api-version=2017-08-01&op=GETCONTENTSUMMARY";
var token = "eyJ0eX.....";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var result = client.GetAsync(url).Result;
var data = result.Content.ReadAsStringAsync().Result;
}
I also test it with PostMan.
Yes, you can use DataLakeStoreFileSystemManagementClient.FileSystem.GetContentSummary:
var client = new DataLakeStoreFileSystemManagementClient(credentials);
ContentSummaryResult result = client.FileSystem.GetContentSummary(dataLakeAccount, path);
var dirSize = result.ContentSummary.Length;
Documentation.