How to connect Azure Scheduler programmatically using .NET - c#

I'm trying to connect my Azure Scheduler via my .Net Application however, at the current state I'm getting KeyNotFoundException: The given key was not present in the dictionary.
I have tried to example in https://github.com/Azure-Samples/scheduler-dotnet-getting-started/tree/master/SchedulerArmSDKTemplate
The problem with the above example is, I think it is based on previous version of the packages. So on the latest version, I tried to make it work by myself but I wasn't able to. The amount of documentation around this and AD Connect is really limited, especially when it comes to new Portal and latest versions. My code sample is below, I'm not sure what I'm doing wrong at this point:
var tenantId = "{tenantId}"; // I have put objectId from Azure AD Properties
var clientId = "{clientId}"; // Here, I have created new App Registration in Azure AD and copied the AppId value
var subscriptionId = "{subscriptionId}"; //Subscription Id of the scheduler resource
UserLoginInformation loginInformation = new UserLoginInformation()
{
ClientId = clientId
};
ServiceClientCredentials serviceClientCredentials = new AzureCredentials(loginInformation, tenantId, AzureEnvironment.AzureGlobalCloud);
SchedulerManagementClient schedulerManagementClient =
new SchedulerManagementClient(serviceClientCredentials) { SubscriptionId = subscriptionId };
var schedulers = await schedulerManagementClient.JobCollections.GetWithHttpMessagesAsync("{resourceGroup}", "{jobCollectionName}");

Tennat Id is not the application objectid. We could get it from the Azure portal, more detail please refer to the screenshot.
If user is not required multi-factor authentication. please have a try to use the following code.
var tenantId = "tenantId"; // Not the object id, it is Azure directory Id
var clientId = "client Id"; // Here, I have created new App Registration in Azure AD and copied the AppId value
var subscriptionId = "subscription Id"; //Subscription Id of the scheduler resource
var resourceGroup = "resource group";
var jobCollectionName = "job name";
UserLoginInformation loginInformation = new UserLoginInformation()
{
ClientId = clientId,
UserName = "xxx#example.com",
Password = "xxxxxx"
};
ServiceClientCredentials serviceClientCredentials = new AzureCredentials(loginInformation, tenantId, AzureEnvironment.AzureGlobalCloud);
SchedulerManagementClient schedulerManagementClient =
new SchedulerManagementClient(serviceClientCredentials) { SubscriptionId = subscriptionId };
var schedulers = await schedulerManagementClient.JobCollections.GetWithHttpMessagesAsync($"{resourceGroup}", $"{jobCollectionName}");

Related

I need to retrieve the Application Insights's InstrumentationKey using C# code

I have created the application Insights using ARM template with C# code.
var creds = new AzureCredentialsFactory().FromServicePrincipal(client, key, tenant, AzureEnvironment.AzureGlobalCloud);
IAzure azure = Microsoft.Azure.Management.Fluent.Azure.Authenticate(creds).WithSubscription(subscription);
IDeployment deployement = azure.Deployments.Define("my-app")
.WithExistingResourceGroup("my-rg-grp")
.WithTemplate(template)
.WithParameters("{}")
.WithMode(DeploymentMode.Incremental)
.CreateAsync();
deployment doesn't have the InstrumentationKey in response.
How could I get the InstrumentationKey just after the Application Insights creation using ARM?
You can use ApplicationInsightsManagementClient class to get the ApplicationInsights resources and the relevant property. The class is defined at Microsoft.Azure.Management.ApplicationInsights v0.3.0-preview package
ApplicationInsightsManagementClient applicationInsightsManagementClient =
new ApplicationInsightsManagementClient(creds) { SubscriptionId = subscriptionId };
var appliationInsightComponents = await applicationInsightsManagementClient.Components.ListAsync();
var requiredApplicationInsightComponent = appliationInsightComponents.SingleOrDefault(a =>
a.ApplicationId.Equals("<<Name of resource>>", StringComparison.OrdinalIgnoreCase));
// to get the InstrumentationKey use
requiredApplicationInsightComponent.InstrumentationKey

AADSTS501051: Application '{API GUID}'(DEV-API) is not assigned to a role for the application '{API GUID}'(DEV-API)

I want to access one API by its Client Credential directly not via any web application
private async Task<string> GetAutheticationToken(string APITypeSelected, string APIKeySelected=null)
{
string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
string tenant = ConfigurationManager.AppSettings["ida:AADTenant"];
string appKey = ConfigurationManager.AppSettings[APIKeySelected];
string apiID = ConfigurationManager.AppSettings[APITypeSelected];
//appKey = HttpUtility.UrlEncode(appKey);
string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
using (HttpClient client = new HttpClient())
{
Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authContext = null;
ClientCredential clientCredential = null;
authContext = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(authority);
//encodeURIComponent(client_secret);
clientCredential = new ClientCredential(apiID, appKey);
AuthenticationResult authResult = null;
authResult = await authContext.AcquireTokenAsync(apiID, clientCredential);
return authResult.AccessToken;
}
}
while executing I am getting bellow error(AADSTS501051) in this line
authResult = await authContext.AcquireTokenAsync(apiID, clientCredential);
AADSTS501051: Application '{API GUID}'(DEV-API) is not assigned to a
role for the application '{API GUID}'(DEV-API).
Do I have to give API permission to itself.
What I need to do.
Thanks,
First you need to make a user role for application if app assignment is required. if not there is no problem. If app assignment is required, Go back to api permission and in my api give permission for the created role, see Microsoft documentation url
https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-protected-web-api-app-registration
Ahh so you want an access token to the API itself? Not sure if that's possible..
If this in another app, it should be registered as another app in Azure AD.
It can then require application permissions on the API and call it via client credentials.
You can see how to define permissions here: https://joonasw.net/view/defining-permissions-and-roles-in-aad
If this is within the same app, it sounds odd that it would acquire a token for itself.
This error message indicates that you need to add an "App role" to your app registration. You can do so by first adding a new App role on {API GUID}
and then assign the app {API GUID} this role (don't forget to give admin consent)
Essentially what is happening here is that your app registration {API GUID} got a role on {API GUID} to create access tokens for the audience {API GUID}, so: itself.
When you use "authContext.AcquireTokenAsync(apiID, clientCredential);" to get the access token, you need to use identifierUri of your ad application as resource.
For example:
string tenantId = "your tenant id or name, for example: hanxia.onmicrosoft.com";
string clientId = "your client id";
string resource = "the identifierUri of your ad application ";
string clientSecret = "";
ClientCredentia clientCredentia = new ClientCredentia(clientId,clientSecret);
var context = new AuthenticationContext("https://login.microsoftonline.com/" + tenantId);
AuthenticationResult result = context.AcquireTokenAsync(resource, clientCredentia);
For more details, please refer to the document.

How to get List of resources by resource type and resource group by using Azure Resource management apis

How to get list of resource for a Resource Group using Azure Resource Management API
I have install Microsoft.Azure.Management.ResourceManager.Fluent Nuget package
The below script only give me only list of resource groups but not list of resources per resource group.
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(clientId, clientSecret, tenantId, AzureEnvironment.AzureGlobalCloud);
var azure = Azure.Configure().Authenticate(credentials).WithSubscription(subscriptionID);
var resourecelist = azure.ResourceGroups.List().ToList();
I am looking for something similar to which is available in powershell
Get-AzureRmResource -ResourceGroupName $batchResourceGroup -ResourceType 'Microsoft.Batch/batchAccounts'
Please have a try to following code to get list of resources. I test it on my side, it works correctly. We also could use the Resources - List By Resource Group Rest API to do that.
var resouceManagementClient = new ResourceManagementClient(credentials) {SubscriptionId = subscriptionId};
var resource = resouceManagementClient.ResourceGroups.ListResourcesAsync(resourceGroup,new ODataQuery<GenericResourceFilterInner>(x=>x.ResourceType == "Microsoft.Batch/batchAccounts")).Result;
The above answer is out-of-date, so here's my code snippet that works in Dec 2020.
Azure.IAuthenticated _azure;
string _subscriptionId;
RestClient _restClient;
async Task Main()
{
Connect();
// Get resource groups
var resourceManagementClient = new ResourceManagementClient(_restClient)
{
SubscriptionId = _subscriptionId
};
var resourceList = (await resourceManagementClient.ResourceGroups.ListAsync()).ToList().OrderBy(r => r.Name);
// ...
}
void Connect()
{
_subscriptionId = "XXX";
var tenantId = "YYY";
var clientId = "ZZZ";
var secret = "QQQ";
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(
clientId, secret, tenantId,
AzureEnvironment.AzureGlobalCloud)
.WithDefaultSubscription(_subscriptionId);
_restClient = RestClient
.Configure()
.WithEnvironment(AzureEnvironment.AzureGlobalCloud)
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.WithCredentials(credentials)
.Build();
var creds = new AzureCredentialsFactory().FromServicePrincipal(
clientId, secret, tenantId,
AzureEnvironment.AzureGlobalCloud
);
_azure = Azure.Authenticate(creds);
}
The usings/imports/NuGet. (you do not need all of these...):
Microsoft.Azure.Management.AppService.Fluent
Microsoft.Azure.Management.AppService.Fluent.Models
Microsoft.Azure.Management.Fluent
Microsoft.Azure.Management.ResourceManager.Fluent
Microsoft.Azure.Management.ResourceManager.Fluent.Authentication
Microsoft.Azure.Management.ResourceManager.Fluent.Core
Microsoft.IdentityModel.Clients.ActiveDirectory
Microsoft.Rest
Microsoft.ServiceBus.Messaging
System.Threading.Tasks
Microsoft.Rest.Azure

Connect to Azure AD using username/password

I have an Azure Api REST which can be reach by entering a username/password .
how can i get access to this API from C# ?
after a little search , i found somthing about using AuthenticationContext .. but it couldn't work for me Authenticationcontext .AcquireToken(resource, clientId, credential);
where can i get the 'resource' parameter and the ClientID .
Thanks a lot
I based most of my work on this post that laid some groundwork.
You need to create a Native Application in your Azure AD first and add the Windows Azure Service Management API permission.
The ClientID is obtained from this App.
This is the code I'm currently using to obtain a Token that can be used with the Management SDK:
string userName = "yourUserName";
string password = "yourPassword";
string directoryName = "yourDirectory.onmicrosoft.com";
string clientId = "{ClientId obtained by creating an App in the Active Directory}";
var credentials= new UserPasswordCredential(string.Format("{0}#{1}", userName, directoryName), password);
var authenticationContext = new AuthenticationContext("https://login.windows.net/" + directoryName);
var result = await authenticationContext.AcquireTokenAsync("https://management.core.windows.net/", clientID, credentials);
var jwtToken = result.AccessToken;
//Example accesing Azure Cdn Management API
string subscriptionId = "xxxx-xxxxxx-xxxx-xxxxxxx";
using (var cdn = new CdnManagementClient(new TokenCredentials(jwtToken)) { SubscriptionId = subscriptionId })
{
//do something...
}
Your directory name can be obtained in the Azure Portal > Azure AD section, on Domain names.

Server-side task to query Office 365 account for new emails

I need a server-side task on my .NET 4.6.1/MVC 5 app that will periodically check a specific O365 email address for new emails and retrieve them if found. This seems like a stupidly simple task, but I cannot find documentation anywhere for creating a server-side process to accomplish this. The only documentation Microsoft seems to have is for OAuth2 and passing through credentials when users sign in. I don't want that. I want to check one specific account, that's it. How would I accomplish this?
These are the pages I've found. There are others, but all are along these lines.
Intro to the Outlook API - I don't see a way to use a service account with the v2 endpoint.
Get Started with the Outlook REST APIs - This is specific to logging users in with OAuth2, unhelpful for my purposes.
Intro to the Outlook API - I don't see a way to use a service account with the v2 endpoint.
The v2 endpoint doesn’t support client credential at present( refer to the limitation). You need to register/configure the app using Azure portal and use the original endpoint to authenticate the app. More detail about register the app please refer to here. And we need to ‘read mail in all mailbox’ to use the client credential to read the messages like figure below.
And here is the code that using client credential to read messages using the Microsoft Graph:
string clientId = "";
string clientsecret = "";
string tenant = "";
string resourceURL = "https://graph.microsoft.com";
string authority = "https://login.microsoftonline.com/" + tenant + "/oauth2/token";
string userMail = "";
var accessToken = new TokenHelper(authority).AcquireTokenAsync(clientId, clientsecret, resourceURL);
var graphserviceClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
(requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.FromResult(0);
}));
var items = await graphserviceClient.Users[user].Messages.Request().OrderBy("receivedDateTime desc").GetAsync();
foreach (var item in items)
{
Console.WriteLine(item.Subject);
}
class TokenHelper
{
AuthenticationContext authContext;
public TokenHelper(string authUri)
{
authContext = new AuthenticationContext(authUri);
}
public string AcquireTokenAsync(string clientId, string secret,string resrouceURL)
{
var credential = new ClientCredential(clientId: clientId, clientSecret: secret);
var result = authContext.AcquireTokenAsync(resrouceURL, credential).Result;
return result.AccessToken;
}
}
In addition, if we authenticate the app with code grant flow we can also create a subscription which notify the app when the mail box receive the new messages.( refer to webhoocks/subscription)

Categories