Getting Registered App Display Name from an App Id - c#

I have an Azure App Id which I have obtained from a token. I would like to get the display name of the application using C# so that I can add it to logs and Application Insights custom properties for a request. It is obviously more human-readable than an Id hence my need.
When I go into the portal I can go to the app registrations and type the AppId in and it shows me the name, so clearly it can be obtained (I can see from the URL https://graph.windows.net/myorganization/applications/?api-version=2.0&$top=40&$filter=appId%20eq%20%27MYAPPID%27), but how do I get this information programmatically in C#?
I could maintain my own lookup table somewhere which converts app ids to names, but this seems pointless when the information is obviously available at runtime.

If you want to get the information about your application in your c# application, you can use Microsoft.Graph.Beta to call the API. For example
Register a new application using the Azure portal
Sign in to the Azure portal using either a work or school account or
a personal Microsoft account.
If your account gives you access to more than one tenant, select your account in the top right corner, and set your portal session to the Azure AD tenant that you want.
In the left-hand navigation pane, select the Azure Active Directory service, and then select App registrations > New registration.
Configure Microsoft Graph permissions you need for your application
Code
/*
install Microsoft.Graph.Beta
install Microsoft.Graph.COre
install Microsoft.Graph.Beta.Auth
*/
string clientId = "your application id";
string appKey = "your client secret";
string tenantId = "your tenant id";
IConfidentialClientApplication confidentialClientApplication =
ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.WithClientSecret(appKey)
.Build();
ClientCredentialProvider authProvider = new
ClientCredentialProvider(confidentialClientApplication);
var apps = graphClient.Applications.Request().Filter("appId eq \'you application id\'").GetAsync().Result;
foreach(var app in apps){
Console.WriteLine(app.DisplayName);
}
For more details, please refer to the document

Related

Not able to get all users from Azure Active Directory

I am using solution mentioned here to get all users from Active Directory however I suspect the code is pulling disabled users from our old Active Directory. The new one is Azure Active Directory. Please let me know what change is required to get below details of only active users from Azure Active Directory:
First Name
Last Name
Email
Enterprise ID
Getting all users in Azure AD can use Microsoft Graph API. Here's the API for listing users. But it doesn't support personal Microsoft account, it only supports work or school accounts. By the way, I'm not sure what is Enterprise ID, could you pls take a look at this section to check if this API contained it?
I assume you have an asp.net core WEB API which is used to getting user list. So you should use code like below.
using Microsoft.Graph;
using Azure.Identity;
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenant_name.onmicrosoft.com";
var clientId = "aad_app_id";
var clientSecret = "client_secret";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var users = await graphClient.Users.Request().GetAsync();
Then an Azure AD application is required for the variables in code above. Pls follow this document to register the Azure AD app. Since my assumption is based on a web API, no need to add redirect URL here. Now we can get tenantId , clientId in Overview blade, and created the client secret. We also need to modify API permissions blade and add required API permissions. What we need is Application permission User.Read.All,User.ReadWrite.All,Directory.Read.All, Directory.ReadWrite.All.

How does one add the "resource principal named https://management.azure.net" to the default directory in Azure?

what I want to do: use the Azure REST API from a custom tool.
What I did:
I created an app registration named CDTester and a secret for it in my default directory. Then I went to the subscription and added the role Contributor to CTTester.
I got a config object cfg loaded from user-secrets with the application id and secret of CDTester and with the tenant id of my default directory.
Now I try to authenticate like this:
var app = ConfidentialClientApplicationBuilder
.Create(cfg.ApplicationId)
.WithTenantId(cfg.LoginTenantId)
.WithClientSecret(cfg.ApplicationSecret)
.Build();
var authResult = await
app.AcquireTokenForClient(new[] {"https://management.azure.net/.default"})
.ExecuteAsync();
The .ExecuteAsynccall fails with
"'
AADSTS500011: The resource principal named https://management.azure.net was not found in the tenant named . This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant."
As a (weak) alternative, I added the Azure Service Management delegated permission to CDTester, gave Admin Consent, switched the code to:
var app = PublicClientApplicationBuilder.Create(cfg.ApplicationId)
.WithTenantId(cfg.LoginTenantId)
.WithDefaultRedirectUri()
.Build();
var authResult = await app
.AcquireTokenInteractive(new[] { "https://management.azure.net/user_impersonation" })
.ExecuteAsync();
ran it, logged in with my own user (who's of course global administrator) and got the same message, this time in the browser right after login.
Changing the scope to "https://management.azure.net/.default" in this flow doesn't change anything either.
So, obviously somehow I need to "install the resource principal https://management.azure.net" into my tenant - but for the life of me, I cannot find how.
As mentioned in the comment, please change https://management.azure.net to https://management.azure.com/.
Essentially there is no such thing as https://management.azure.net. To get an access token so that you can execute Azure Resource Manager API, you will need to acquire a token for https://management.azure.com/ resource.

Call Azure AD protected Azure Function from console app/PowerShell w/delegated permission

What I want to do is have the user log in to the AAD prompt on their Windows Desktop machines, so I get a Bearer token that will work with my Azure Function.
I've followed the tutorial from this article on adatum but it only covers the application permission (not delegated permissions)
I already have an Azure Function that is set up for Azure AD
authentication.
I already have a client app that I registered (under
App Registrations).
I've configured it to use delegated permissions
for the Azure Function.
Here's my client code:
var clientId = "client id for my console app";//console app
var clientUrl = new Uri("https://login.microsoftonline.com/common/oauth2/nativeclient");
var tenant = "tenantid here";
string authority = "https://login.windows.net/" + tenant;
string resource = "https://myaadProtectedFunc.azurewebsites.net";
AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
var pp = new PlatformParameters(PromptBehavior.Auto);
var token = authenticationContext.AcquireTokenAsync(resource, clientId, clientUrl,
pp, UserIdentifier.AnyUser).Result;
Console.WriteLine("Got the token: {0}", token.AccessToken);
I get an error saying "[my client app] needs permission to access resources in your organization that only an admin can grant. Please ask an admin to grant permission to this app before you can use it."
Is there some other way to get a Bearer token that will work with my Azure Function?
I did a test and your code does work if you set up the azure side correctly. most likely in the azure function you do not have it set up correctly.
in the azure function did you set up the service principal?
eg. function app -> platform features -> authentication / authorization -> App Service Authentication to ON -> select azure active directory -> express -> create. -> press ok. -> save.
then in your app registration, you will now see 2. the app reg for your client, and app reg for your function app. in the app reg for your client go to api permissions and add the app registration for your function app with the user impersonation selected.
finally make sure your enterprise application has the user/groups you want to be allowed to access for each of the enterprise apps. (client and function app registration)
Hope that helps.
Ok it turns out that I don't need to make a separate client application at all.
I can just use the Client ID of the Azure Function.
The thing is that you will have to go to 'Advance' instead of 'Express' because the library Microsoft.Identity.Client uses v2.0 tokens.
This is to configure your Azure Function - keep all fields the same, but add a /v2.0 to the Issuer URL:
This is the code to get the delegated bearer token for the Azure Function, which uses the v2.0 token - I don't know how to change it to use the v1 token:
string[] scopes = new string[] { "profile", "email", "openid" };
string ClientId = [clientId of Azure Function];
string Tenant = [tenantId];
string Instance = "https://login.microsoftonline.com/";
var _clientApp = PublicClientApplicationBuilder.Create(ClientId)
.WithAuthority($"{Instance}{Tenant}")
.WithDefaultRedirectUri()
.Build();
var accounts = _clientApp.GetAccountsAsync().Result;
var authResult = _clientApp.AcquireTokenInteractive(scopes)
.WithAccount(accounts.FirstOrDefault())
.WithPrompt(Prompt.SelectAccount)
.ExecuteAsync().Result;
var bearerTokenForAzureFunction = authResult.IdToken;
Now I don't understand the need to register a client application at all if I can get the delegated bearer token this way...

Azure AD Application - Require Role Assignment + Add a role assignment for an Application?

I have an MVC Web Application (WebAPI + Angular) deployed to Azure as a Web App (not API App) that is setup to be secured using Settings -> Authentication / Authorization -> AAD -> Express. This created an AD Application with the same name as the Web App, and as a normal web user (in the directory, using OAuth) this works as expected.
But I also have external automation that needs to call the WebAPI controllers directly, so I need to programmatically get a Bearer token to pass along with those requests.
This all works OK when "USER ASSIGNMENT REQUIRED TO ACCESS APP" == NO. But this won't suffice because everyone in the Directory shouldn't have access to this app.
Flipping that switch results in the error:
Application 'AppId' is not assigned to a role for the application 'AppId'.
The code being used:
var aadLoginUri = "http://login.microsoftonline.com/{0}";
var tenantId = "[xxx].onmicrosoft.com";
var authority = String.Format(CultureInfo.InvariantCulture, aadLoginUri, tenantId);
var clientId = ConfigurationManager.AppSettings["ClientId"];
var clientSecret = ConfigurationManager.AppSettings["ClientSecret"];
var authContext = new AuthenticationContext(authority);
ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
AuthenticationResult authResult = authContext.AcquireToken(clientId, clientCredential);
How can I add a role assignment for an Application?
(as opposed to for a user)
I tried utilizing the 'permissions to other applications' section, but an app cannot be added to itself. To see if this would solve the problem from another app, I went ahead and created one and was able to add the App & set Delegated Permissions to 'Access [App Name]'. But just as before, this only works if user assignment is not required to access the app. Afterwards AcquireToken() throws the same exception.
It seems this issue could be solved by decoupling our API from the Angular app, hosting the API as an API App (with a Gateway), but that's not an option at the moment. Also this article says this new Auth feature "replaces the App Service gateway for most applications" and this blog post announcing the feature in November says "We recommend web and mobile applications use this feature instead of the App Service gateway going forward" so I wonder if this just hasn't made it into the UI & perhaps it's possible to add app role assignments via the app manifest (tried, failed), graph/service-mgmt api, powershell, etc.
The key is to define the correct appRoles (with the correct allowedMemberType) in the manifest.
In the Azure Portal, configure the following:
In the resource that needs to be accessed, open the manifest ('App Registrations' blade). In the appRoles array, add two roles:
One of allowedMemberType 'Application'
One of allowedMemberType 'User'
Save the manifest.
Next, in the client app that needs to access the resource:
Browse to 'Required Permissions' and click 'Add'
Search for the resource you want to access
In the 'Enable Access' section, under 'Application Permissions', select the role you just configured
Save and click 'Grant permissions'
To configure the user permissions:
Browse to the 'Enterprise Applications' blade
Select 'All Application', then select the correct app
Click 'Users and Groups'
Assign users to roles
In the Properties section, keep the 'User assignment required?' checkbox enabled. This will restrict access to configured users only.
Now you can access the resource both as a user and as an application.
How can I add a role assignment for an Application?
1) Download Manifest from Application page as follow:
2)Add role content in Manifest like below. An user can be assigned to an application as an user role, group, application also can be assigned to application as a role.
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"description": "Admins can manage roles and perform all actions.",
"displayName": "Global Admin",
"id": "7c93906c-71fa-4e5b-b1da-21b073d298fd",
"isEnabled": true,
"value": "Admin"
}
]

Openstack.Net SDK cannot access services

We've setup an OpenStack system on our own hardware installing all components, with everything seemingly fine as we've created networks and VMs through the web interface.
I'm trying to use openstack.net SDK to do things programatically. I seem to be able to Authenticate fine using a username and password, but when it comes to accessing other services that are installed, we get errors suggesting the API endpoints aren't available to the user.
The code we're using is below which works fine until the CreateServer line at which point I get the error
"Unable to authenticate user and retrieve authorized service endpoints."
Uri baseUrl = new Uri("http://mycloudip:5000/v2.0");
CloudIdentity cloudId = new CloudIdentity()
{
Username = userName,
Password = password
};
CloudIdentityProvider cip = new CloudIdentityProvider(cloudId, baseUrl);
UserAccess ua = cip.Authenticate(cloudId);
CloudServersProvider provider = new CloudServersProvider(cloudId);
Metadata metaData = new Metadata(); // Add some metadata just because we can
metaData.Add("Description", "Example 4 - Getting Started");
string serverName = "Example4";
string imageId = "48df4181-040e-4821-8723-d9e4ba908d2f";
string flavorId = "3";
NewServer newServer = provider.CreateServer(serverName, imageId, flavorId, DiskConfiguration.Manual, metaData);
I can see all the service urls in the Access and Security >> API Endpoints section whilst logged on as the same user in the dashboard, but UserAccess.ServiceCatalog doesn't seem to be populated with anything.
Any help or pointers much appreciated.
The default IIdentityProvider used by the CloudServersProvider implementation in openstack.net SDK 1.3.2.0 is designed around the authentication requirements for Rackspace. In order to authenticate against a different OpenStack-compatible installation, you'll need to follow the steps described in the following documentation:
OpenStack Authentication (openstack.net API Reference Documentation)
The following is an excerpt of the current documentation:
This page describes the process for authenticating against reference OpenStack installations, including but not limited to DevStack and the Rackspace Private Cloud.
Usage Notes
Client authentication against a reference OpenStack installation requires the following.
Create an instance of CloudIdentityWithProject and initialize its properties with the desired authentication credentials. The CloudIdentityWithProject credentials class allows the tenantName and tenantId properties described in the OpenStack documentation to be defined.
Create an instance of OpenStackIdentityProvider, and pass the previously created credentials to the constructor.
When creating a service provider instance, such as CloudFilesProvider or CloudQueuesProvider, pass null for the CloudIdentity parameter and the identity provider from the previous step as the IIdentityProvider parameter.
Limitations
The OpenStackIdentityProvider only supports authentication using username and password credentials, along with optionally specifying the tenant name and/or tenant ID (referred to as the project name and ID starting with the Identity Service API v3).

Categories