I'm trying to authenticate a request to Dynamics using the app's client id and the application key. This is failing in a web app project in visual studio (debugging locally). Below is the code I'm trying to use. It looks like I'm getting an auth token back to pass in but it throws this error:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Bearer authorization_uri=https://login.windows.net/....
string organizationUrl = "https://myurl.dynamics.com";
string clientId = "myclientid";
string appKey = "myclientsecret";
string aadInstance = "https://login.microsoftonline.com/";
string tenantID = "mytenantid";
ClientCredential clientcred = new ClientCredential(clientId, appKey);
AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID);
AuthenticationResult authenticationResult = authenticationContext.AcquireToken(organizationUrl, clientcred);
var requestedToken = authenticationResult.AccessToken;
using (var sdkService = new OrganizationWebProxyClient(GetServiceUrl(organizationUrl), false))
{
sdkService.HeaderToken = requestedToken;
OrganizationRequest request = new OrganizationRequest()
{
RequestName = "WhoAmI"
};
WhoAmIResponse response = sdkService.Execute(new WhoAmIRequest()) as WhoAmIResponse;
Console.WriteLine(response.UserId);
}
Related
I need to get the keys through code, not through a portal. For doing this I have found REST API in Google.
This is the link to Azure Key management API, but do this we need to do an authentication.
We have to develop all this using C# only.
Regarding the issue, please refer to the following code.
#install Microsoft.Azure.Management.ResourceManager.Fluent and Microsoft.Azure.Management.Fluent
string clientId = "client id";
string secret = "secret key";
string tenant = "tenant id";
var functionName ="functionName";
var webFunctionAppName = "functionApp name";
string resourceGroup = "resource group name";
var credentials = new AzureCredentials(new ServicePrincipalLoginInformation { ClientId = clientId, ClientSecret = secret}, tenant, AzureEnvironment.AzureGlobalCloud);
var azure = Azure
.Configure()
.Authenticate(credentials)
.WithDefaultSubscription();
var webFunctionApp = azure.AppServices.FunctionApps.GetByResourceGroup(resourceGroup, webFunctionAppName);
var ftpUsername = webFunctionApp.GetPublishingProfile().FtpUsername;
var username = ftpUsername.Split('\\').ToList()[1];
var password = webFunctionApp.GetPublishingProfile().FtpPassword;
var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}"));
var apiUrl = new Uri($"https://{webFunctionAppName}.scm.azurewebsites.net/api");
var siteUrl = new Uri($"https://{webFunctionAppName}.azurewebsites.net");
string JWT;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", $"Basic {base64Auth}");
var result = client.GetAsync($"{apiUrl}/functions/admin/token").Result;
JWT = result.Content.ReadAsStringAsync().Result.Trim('"'); //get JWT for call funtion key
}
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + JWT);
var key = client.GetAsync($"{siteUrl}/admin/functions/{functionName}/keys").Result.Content.ReadAsStringAsync().Result;
}
Besides, you also can refer to the document.
I want to use microsoft graph in web api which is using .net core 2.0, I want to authenticate user without login prompt.
Following is the code I have used, Please correct me if my method is wrong.
string clientId = "";
string clientsecret = "";
string tenant = "";
string resourceURL = "https://graph.microsoft.com";
string userMail = "testuser3#company.com";
public async Task<string> GetMyEmailUser()
{
try
{
var result = "";
string AzureADAuthority = "https://login.microsoftonline.com/companyname.com";
AuthenticationContext authenticationContext = new AuthenticationContext(AzureADAuthority, false);
var credential = new ClientCredential(clientId, clientsecret);
var authenticationResult = authenticationContext.AcquireTokenAsync(resourceURL, credential).Result;
var token = authenticationResult.AccessToken;
using (var confClient = new HttpClient())
{
var url = "https://graph.microsoft.com/v1.0";
confClient.BaseAddress = new Uri(url);
confClient.DefaultRequestHeaders.Accept.Clear();
confClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
confClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = confClient.GetAsync(url + "/me/mailFolders/inbox/messages?$filter=isRead eq false&$top=100").Result;
var jsonString = JObject.Parse(await response.Content.ReadAsStringAsync());
IUserMessagesCollectionPage myDetails = JsonConvert.DeserializeObject<IUserMessagesCollectionPage>(jsonString["value"].ToString());
}
I am new to microsoft graph and would really appreciate your help. Thanks.
I need list of Azure storage from my subscription ID and authentication token.
I am doing code as per reference -`
https://msdn.microsoft.com/en-us/library/azure/ee460787.aspx?f=255&MSPPError=-2147217396
But I am not able to get that data and in response I am only getting code 401 Unauthorized access
I have tried code in c# as per below -
Get Authorization Token -
private static string GetAuthorizationToken()
{
ClientCredential cc = new ClientCredential(ClientId, ServicePrincipalPassword);
var context = new AuthenticationContext("https://login.windows.net/" + AzureTenantId);
var result = context.AcquireTokenAsync("https://management.azure.com/", cc);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
return result.Result.AccessToken;
}
And then
AuthToken = GetAuthorizationToken();
TokenCredentials = new TokenCredentials(AuthToken);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://management.core.windows.net/<My Subscription ID>/services/storageservices");
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + AuthToken);
request.ContentType = "application/json";
request.Method = "GET";
//request.Headers["Authorization"] = "Bearer " + AuthToken; // Also tried this
request.Headers["x-ms-version"] = "2016-05-31";//
//https://management.core.windows.net/<subscription-id>/services/storageservices
//header - "x-ms-version"
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
//ex.Message;
}
Please suggest any solution to get storage account list from Subscription ID and Authentication token. and if you have any better solution other then this to get storage list then also please suggest.
I use the below function to create similar requests:
private static async Task<HttpWebRequest> createHttpRequestWithToken(Uri uri)
{
HttpWebRequest newRequest = (HttpWebRequest)HttpWebRequest.Create(uri);
string clientId = ConfigurationManager.AppSettings["ClientId"]);
string clientSecret = ConfigurationManager.AppSettings["ClientSecret"]);
ClientCredential creds = new ClientCredential(clientId, clientSecret);
AuthenticationContext authContext = new AuthenticationContext(string.Format("https://login.microsoftonline.com/{0}/", ConfigurationManager.AppSettings["OrganizationId"]));
AuthenticationResult authResult = await authContext.AcquireTokenAsync("https://management.core.windows.net/", creds);
newRequest.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + authResult.AccessToken);
return newRequest;
}
And create request like this:
HttpWebRequest request = createHttpRequestWithToken(uri).Result;
Additionally, Windows Azure Service Management API needs to be granted permission to access the resources. This can be done in the Configure tab in AD Service Principal.
To list all the storage accounts available under the subscription, you could try to use:
GET /subscriptions/{subscriptionId}/providers/Microsoft.Storage/storageAccounts?api-version=2016-01-01
the following sample code works fine on my side, please refer to it.
string tenantId = "xxxx";
string clientId = "xxxx";
string clientSecret = "xxxx";
string subscriptionid = "xxxx";
string authContextURL = "https://login.windows.net/" + tenantId;
var authenticationContext = new AuthenticationContext(authContextURL);
var credential = new ClientCredential(clientId, clientSecret);
var result = await authenticationContext.AcquireTokenAsync(resource: "https://management.azure.com/", clientCredential: credential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format("https://management.azure.com/subscriptions/{0}/providers/Microsoft.Storage/storageAccounts?api-version=2016-01-01", subscriptionid));
request.Method = "GET";
request.Headers["Authorization"] = "Bearer " + token;
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
//ex.Message;
}
response in fiddler looks like this.
Besides, please make sure if you assign the application to a role, if not assign the application to a role, 403 error will appear.
I'm using OAuth2 credentials, getting 404 error:
using Google.Analytics;
using Google.GData.Analytics;
void Analytics()
{
try
{
string userName = ConfigurationManager.AppSettings["username"];
string passWord = ConfigurationManager.AppSettings["password"];
string gkey = "key=api _key";
string dataFeedUrl = "https://www.googleapis.com/analytics/v3/data/ga";//+ gkey;
AccountQuery query = new AccountQuery();
AnalyticsService service = new AnalyticsService("Web App");
service.setUserCredentials(userName, passWord);
DataQuery query1 = new DataQuery(dataFeedUrl);
query1.Ids = "ga:123456789";
query1.Metrics = "ga:visits,ga:sessions,ga:pageValue,ga:bounces,ga:bounceRate,ga:pageviews";
query1.Dimensions = "ga:city,ga:date";
query1.GAStartDate = ("2016-03-15");//DateTime.Now.AddMonths(-1).AddDays(-2).ToString("yyyy-MM-dd");
query1.GAEndDate = ("2016-03-17");//DateTime.Now.AddDays(-3).ToString("yyyy-MM-dd");
query1.ExtraParameters = gkey;
DataFeed dataFeedVisits = service.Query(query1);
foreach (DataEntry entry in dataFeedVisits.Entries)
{
string st = entry.Title.Text;
string ss = entry.Metrics[0].Value;
int _intVisists = Int32.Parse(ss);
Response.Write("<br/>");
Response.Write("Total Visits : " + ss);
Response.Write("<br/>");
}
}
catch (Exception ex)
{
Response.Write("Error : " + ex);
}
}
Exception is :
Execution of request failed: https://www.googleapis.com/analytics/v3/data/ga?key=api_key&dimensions=ga:city,ga:date&end-date=2016-03-17&ids=ga:123456789&metrics=ga:visits,ga:sessions,ga:pageValue,ga:bounces,ga:bounceRate,ga:pageviews&start-date=2016-03-15
Somehow its redirecting to https://www.google.com/accounts/ClientLogin which is shutdown by google.
client login was shut down in May 2015, there for you need to use Open authentication.
you are using the GData library which requires data be returnd as XML.
you are requesting against the Google Analytics V3 API, which is not a gdata api and returns data as JSon.
Solution:
Install the current version of the Google .net client library
PM> Install-Package Google.Apis.Analytics.v3
Authentication:
string[] scopes = new string[] {AnalyticsService.Scope.AnalyticsReadonly}; // View Google Analytics Data
var clientId = "[Client ID]"; // From https://console.developers.google.com
var clientSecret = "xxx"; // From https://console.developers.google.com
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId,
ClientSecret = clientSecret},
scopes,
Environment.UserName,
CancellationToken.None,
new FileDataStore("Daimto.GoogleAnalytics.Auth.Store")).Result;
create an analytics service
var service = new AnalyticsService(new BaseClientService.Initializer() { HttpClientInitializer = credential,
ApplicationName = "Analytics API Sample",});
request data
DataResource.GaResource.GetRequest request = service.Data.Ga.Get("ga:8903098", "2014-01-01", "2014-01-01", "ga:sessions");
request.MaxResults = 1000;
GaData result = request.Execute();
code ripped from my Google Analytis api tutorail
I am using Azure REST API for fetching Billing Usage and Ratecard details.
To acquire Token using AcquireToken() Method, initially I used only Client Id which then asks for User Credentials in login window.
However, I am looking for Non-Interactive Approach, so I used Client Credentials in which I passed Client Id and Client Secret Key.
But it gives "Remote Server returns an error 401 Unauthorized"
When I look into error deeply, I found that it gives error "The access token is from wrong audience or resource"
Please give me any solution using which I can access the API without any user interaction.
Thanks in Advance.
Here is my code:
{
string token = GetOAuthTokenFromAAD();
string requestURL = String.Format("{0}/{1}/{2}/{3}",
ConfigurationManager.AppSettings["ARMBillingServiceURL"],
"subscriptions",
ConfigurationManager.AppSettings["SubscriptionID"],
"providers/Microsoft.Commerce/RateCard?api-version=2015-06-01-preview&$filter=OfferDurableId eq 'MS-AZR-*****' and Currency eq 'INR' and Locale eq 'en-IN' and RegionInfo eq 'IN'");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
request.ContentType = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(String.Format("RateCard service response status: {0}", response.StatusDescription));
}
public static string GetOAuthTokenFromAAD()
{
AuthenticationContext authenticationContext = new AuthenticationContext(string.Format("{0}/{1}",ConfigurationManager.AppSettings["ADALServiceURL"], ConfigurationManager.AppSettings["TenantDomain"]));
AuthenticationResult result = null;
ClientCredential uc = new ClientCredential(Client_Id, Secret_Key);
try
{
result = authenticationContext.AcquireToken("https://management.core.windows.net/", uc);
}
return result.AccessToken;
}
//App Config File
<add key="ADALServiceURL" value="https://login.microsoftonline.com" />
<add key="ADALRedirectURL" value="http://*****-authentication.cloudapp.net" />
<add key="ARMBillingServiceURL" value="https://management.core.windows.net" />
<add key="TenantDomain" value="********.onmicrosoft.com" />
<add key="SubscriptionID" value="*******-****-****-****-********" />
<add key="ClientId" value="*******-****-****-****-********" />
Update: I have also provided these methods as a Reusable Authentication Helper Class Library. You can find the same at this link:
Azure Authentication - Authenticating any Azure API Request in your Application
Method 1: To use the password approach non-interactively you need to first follow the below post's section "Authenticate with password - PowerShell":
Authenticating a service principal with ARM
Then use the below code snippet to fetch token.
var authenticationContext = new AuthenticationContext(String.Format("{0}/{1}",
ConfigurationManager.AppSettings["ADALServiceURL"],
ConfigurationManager.AppSettings["TenantDomain"]));
var credential = new ClientCredential(clientId: "11a11111-11a1-111a-a111-1afeda2bca1a", clientSecret: "passwordhere");
var result = authenticationContext.AcquireToken(resource: "https://management.core.windows.net/", clientCredential: credential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
string token = result.AccessToken;
return token;
Alternatively (Method 2), you can also use the certificate method. In that case use the same link as above but follow section "Authenticate with certificate - PowerShell" from that link. Then use the below code snippet to fetch the token non-interactively:
var subscriptionId = "1a11aa11-5c9b-4c94-b875-b7b55af5d316";
string tenant = "1a11111a-5713-4b00-a1c3-88da50be3ace";
string clientId = "aa11a111-1050-4892-a2d8-4747441be14d";
var authContext = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenant));
X509Certificate2 cert = null;
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
string certName = "MyCert01";
try
{
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var certs = certCollection.Find(X509FindType.FindBySubjectName, certName, false);
//var certs = certCollection.Find(X509FindType.FindBySerialNumber, "E144928868B609D35F72", false);
if (certs == null || certs.Count <= 0)
{
throw new Exception("Certificate " + certName + " not found.");
}
cert = certs[0];
}
finally
{
store.Close();
}
var certCred = new ClientAssertionCertificate(clientId, cert);
var token = authContext.AcquireToken("https://management.core.windows.net/", certCred);
var creds = new TokenCloudCredentials(subscriptionId, token.AccessToken);
//var client = new ResourceManagementClient(creds);
return token.AccessToken;