Authorization exception with Azure using C# and Microsoft.Azure.Management.Fluent - c#

I am a student and I am currently trying to learn Azure platform and how to use the C# libraries to manage it.
I was able to create, delete blob and files with no problem using the package WindowsAzure.Storage.
Then I wanted to list VMs using this tutorial : https://learn.microsoft.com/en-us/azure/virtual-machines/windows/csharp
This is my code:
var credentials = SdkContext.AzureCredentialsFactory.FromFile(Environment.GetEnvironmentVariable("AZURE_AUTH_LOCATION"));
var azure = Azure
.Configure()
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.Authenticate(credentials)
.WithDefaultSubscription();
Console.WriteLine(azure.VirtualMachines.List().Count());
My connection file look like this:
subscription=********-****-****-****-************
client=********-****-****-****-************
key=qeFkWjPm0YHn5xw8UMS2ytLhf9Oi0rEMxZVOTpk3aMQ=
tenant=********-****-****-****-************
managementURI=https://management.core.windows.net/
baseURL=https://management.azure.com/
authURL=https://login.windows.net/
graphURL=https://graph.windows.net/
But I get this error:
Unhandled Exception: Microsoft.Rest.Azure.CloudException: The client '********-****-****-****-************' with object id '********-****-****-****-************' does not have authorization to perform action 'Microsoft.Compute/virtualMachines/read' over scope '/subscriptions/********-****-****-****-************'.
There is two weird things I noticed :
1 - In the exception message, the client id and object id are the same and I dont know where they come from.
2 - When I create a new application registration on AzureAD, I can't see it in "My apps" but only in "All Apps", and I cant add myself as an owner.
Click here to see a screenshot
I have searched for 2 days and I cant figured out why it's not working.
(This is a simple .Net Core 2 console project, I am on Linux if it can help to find out)
Thank you in advance.
Edit #1 :
Thank's to #juunas, working now.
Help link: https://learn.microsoft.com/en-US/azure/azure-resource-manager/resource-group-create-service-principal-portal#assign-application-to-role

To read details about a VM, the application should have a Reader role on the VM, its resource group, or the subscription. If you need to modify things, Contributor allows all modifications. You should add the application to a role via the Access Control IAM tab on the subscription/resource group/resource.

Related

Azure error: DefaultAzureCredential authentication failed

I am working on the Official Azure sample: Getting started - Managing Compute Resources using Azure .NET SDK. And getting the following error on line resourceGroup = await resourceGroups.CreateOrUpdateAsync(resourceGroupName, resourceGroup); of the following code where app is trying to create a Resource Group. I have followed the instructions for Registering an app and from this link provided by the sample. And, have assigned a role to app as follows:
Error:
Azure.Identity.AuthenticationFailedException
HResult=0x80131500
Message=DefaultAzureCredential authentication failed.
Source=Azure.Identity
Inner Exception 2:
MsalServiceException: AADSTS70002: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal
static async Task Main(string[] args)
{
var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
var resourceClient = new ResourcesManagementClient(subscriptionId, new DefaultAzureCredential());
// Create Resource Group
Console.WriteLine("--------Start create group--------");
var resourceGroups = resourceClient.ResourceGroups;
var location = "westus2";
var resourceGroupName = "QuickStartRG";
var resourceGroup = new ResourceGroup(location);
resourceGroup = await resourceGroups.CreateOrUpdateAsync(resourceGroupName, resourceGroup);
Console.WriteLine("--------Finish create group--------");
// Create a Virtual Machine
await Program.CreateVmAsync(subscriptionId, "QuickStartRG", location, "quickstartvm");
// Delete resource group if necessary
//Console.WriteLine("--------Start delete group--------");
//await (await resourceGroups.StartDeleteAsync(resourceGroupName)).WaitForCompletionAsync();
//Console.WriteLine("--------Finish delete group--------");
//Console.ReadKey();
}
UPDATE:
As per instructions in the sample, following is how I Used the portal to create an Azure AD application and service principal that can access resources. I may not have done something right here. Please let me know what I am not doing right here:
Role Assignment for the registered app in Access Control (IAM):
Authentication and Direct URI:
API Permissions for the Registered App:
UPDATE-2:
Working with #JoyWan, I was able to resolve the issue (thank you Joy). Below is the screenshot of successful creation of all required compute resources including VM. NOTE: Clicking on the image would provide a better view of the screenshot.
I test the code, it works fine on my side. The steps you mentioned are also correct.
In this sample, the DefaultAzureCredential() actually uses the EnvironmentCredential() in local, so if you run the code in local, make sure you have Set Environment Variables with the AD App Client ID, Client Secret, Tenant ID.
Update:
From #nam's comment, the issue was that environment vars were not refreshed yesterday, since he had shutdown the machine yesterday and restarted it again today, the environment var got in sync and hence the app started working.

Cannot see my graph on JanusGraph Server with BerkeleyDB storage from .NET client

Can someone help me to understand why I don't see the graph from JanusGraph.Net client?
I'm running the latest Docker image for JanusGraph from Docker Hub. After connecting to the JanusGraph using the built-in console I created a sample Graph of the Gods and was able to query it using the following commands:
graph = JanusGraphFactory.open('conf/janusgraph-berkeleyje-lucene.properties')
GraphOfTheGodsFactory.load(graph)
g = graph.traversal()
g.V().count()
Because the graph remained across container restarts (was able to query it again without GraphOfTheGodsFactory.load(graph) command) and some files were created inside the /opt/janusgraph/db/berkeley/ folder I assume that everything works.
Then I updated the graphs.graph property of the /opt/janusgraph/conf/gremlin-server/gremlin-server.yaml (path taken from docker-entrypoint.sh) to this value:
graphs: {
graph: conf/janusgraph-berkeleyje-lucene.properties
}
and restarted container.
After that I created a simple .NET console application using JanusGraph.Net from with the following code:
static void Main(string[] args)
{
var client = JanusGraphClientBuilder
.BuildClientForServer(new GremlinServer("localhost", 8182))
.Create();
var g = AnonymousTraversalSource
.Traversal()
.WithRemote(new DriverRemoteConnection(client));
var count = g.V().Count().Next();
}
and the count variable is always zero. It looks like that my .NET application connected to some another (probably in-memory) empty graph on this server.
What else should I change or update? Please help to figure this out.
OK, it was not very obvious, but JanusGraph Docker image is pre-configured to use BerkeleyDB by default (BTW according to the documentation it should be Cassandra). I found it taking a look at the Gremlin Server logs. Gremlin Server is configured to use /etc/opt/janusgraph/janusgraph.properties on startup. This file contains a completely different configuration for BerkeleyDB than, for example, conf/janusgraph-berkeleyje.properties - different folders, etc. That is why my .NET application hasn't seen any data - it was connected (through Gremlin Server) to the different BerkeleyDB database.
I also wasn't able to load this file to the Gremlin console via graph = JanusGraphFactory.open('/etc/opt/janusgraph/janusgraph.properties') - got access issues. After I copied this file to the conf directory (and changed the access rights) - I got another error: Could not instantiate implementation: org.janusgraph.diskstorage.berkeleyje.BerkeleyJEStoreManager probably because the BerkeleyDB already exists.
So the only way I've figured out how to connect to the existing database via the Gremlin Console is to use the :remote connect command. I was able to load a sample "Graph of the Gods" database and later access it from my .NET application using the following commands:
:remote connect tinkerpop.server conf/remote.yaml
:> GraphOfTheGodsFactory.load(graph)
:> g.V().count()
==>12

Accessing a local instance of the bot framework using DirectLine

I have a bot (basically a clone of the echo bot) and I'm running the service locally. Is it possible to use the Direct Line API to access it (I'm using the NuGet package: Microsoft.Bot.Connector.DirectLine), and I'm trying to access it like this:
DirectLineClient client = new DirectLineClient();
client.BaseUri = new Uri($"http://localhost:3978/api/messages");
var conversation = await client.Conversations.StartConversationAsync().ConfigureAwait(false);
However, conversation is always null. Is it possible to connect to the service locally, or does it have to be deployed to Azure? If the former, then what could I be doing wrong?
Any help would be appreciated.
The Offline-directline package is a way to set up a node server and use directline/webchat to connect to it as if it were a azure endpoint.
You're basically going to follow the usage instructions as they're laid out:
1) Install offline-directline (OD) package
2) Create the OD server using node
3) Run your bot
4) Connect to your bot through a custom webchat that looks to the OD server from step 2 instead of localhost or an azure endpoint

Can't Seem to See Custom Telemetry in App Insights

I tried adding custom telemetry per the docs (https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-telemetry?view=azure-bot-service-4.0).
I am missing something because I cannot find my custom event in the App Insights logs.
I tried interacting with the bot and searching the App Insights logs for "VeryImportantProperty" and "VeryImportantValue"
I wrote this class:
public class TelemetryMiddleware : TelemetryLoggerMiddleware
{
public TelemetryMiddleware(IBotTelemetryClient telemetryClient, bool logPersonalInformation)
: base(telemetryClient, logPersonalInformation)
{
}
protected override async Task OnReceiveActivityAsync(Activity activity, CancellationToken cancellation)
{
Dictionary<string, string> propertyItems = new Dictionary<string, string>
{
{"VeryImportantProperty", "VeryImportantValue" }
};
var properties = await FillReceiveEventPropertiesAsync(activity, propertyItems);
TelemetryClient.TrackEvent(TelemetryLoggerConstants.BotMsgReceiveEvent, properties);
}
}
I added it in startup.cs as a service available for injection:
services.AddSingleton<IMiddleware, TelemetryMiddleware>();
I also added all the other items named in the article required as injectable services.
I deployed the bot and interacted with it, but I cannot find my VeryImportantValue or property even after a full search of my App Insights logs.
I’m sure I am missing something, but from the docs, I cannot determine what it is.
Any ideas or pointers in the right direction?
You should be able to see these events by going to Azure Portal > All Resources > Application Insights Resource > Overview page > Logs (Analytics) which is along the top, above the details for the Application Insights resource.
Then if you enter the following for your query:
customEvents
| where name == "BotMessageReceived"
and click run (you may have to select the query text you entered before clicking run.
Your VeryImportantProperty data should show under the customDimensions column.
The getting started information is available here.
Edit
If you still cannot see the log entries then you will need to debug where the issue is. The steps I would recommend are:
Get the latest version of the Bot Framework Emulator.
Update your TelemetryMiddleware class to have a the following field private IBotTelemetryClient _telemetryClient;
Update your TelemetryMiddleware constructor to assign the value from the telemetryClient parameter to your new _telemetryClient field.
Update the call inside OnReceiveActivityAsync to use the new _telemetryClient field instead of the TelemetryClient class (you are calling TrackEvent statically currently which isn't what you want.
Run your bot locally using the Bot Framework Emulator.
Add a breakpoint on the line where you call TrackEvent
Create the scenario which should trigger OnReceiveActivityAsync (send a message to the bot).
Use F10 to step over the TrackEvent line and ensure that it is called successfully.
At this stage I would also inspect your variables to ensure they have the values that you expect.
Wait for the event to flow through to App Insights (might take up to 5 minutes).
If this still does not work I would create a new Application Insights API key and updating the following places with the new value:
For local testing:
Your appsettings.json file so that you can test locally.
For production:
The Application Insights Instrumentation key under the Settings tab of your Web App Bot in Azure.
Also check that the value for Application Insights Application Id under the Settings tab of your Web App Bot in Azure matches the Application Id value under the API Access tab of your Application Insights resource.
Follow the steps above to test locally using the emulator.
Once the logs are flowing through locally use the Test in Web Chat functionality to ensure that it is working in production.

Active Directory List of Users

I have been asked to write a small utility to copy users from an AD to another system.
I found this posting which looks perfect to get me going...
How can I get a list of users from active directory?
As I don't have an AD to work with, I went to my Azure portal and created one on there to test against...
Then, it looked like all I needed to do was insert my domain in this line....
using (var context = new PrincipalContext(ContextType.Domain, "yourdomain.com"))
My domain, as supplied by Azure is xxxx.onmicrosoft.com
but when I run the code, I keep getting
An unhandled exception of type 'System.DirectoryServices.AccountManagement.PrincipalServerDownException' occurred in System.DirectoryServices.AccountManagement.dll
Additional information: The server could not be contacted.
Can anyone see what I am missing please?
i borrowed my mates old server and built a local server 2012 and joined the domain.
probably not everyone's answer. but worked for me.
(if i had more time i would have liked to get the azure domain working... im sure i built it right. just didn't work.
so that's my answer.

Categories

Resources