C# How to get list of users in all roles in RBAC defined in a subscription using Microsoft.Azure.Management.Graph.RBAC.Fluent - azure

How to get a list of users in all roles in RBAC defined in a subscription.
var authorityUri = $"https://login.microsoftonline.com/{tenantId}";
var scopes = new System.Collections.Generic.List<string> { "https://graph.microsoft.com/.default" };
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(appId, clientSecret, tenantId, AzureEnvironment.AzureGlobalCloud);
var authenticated1 = Microsoft.Azure.Management.Fluent.Azure.Configure().Authenticate(credentials);
IRoleDefinition Rdef = authenticated1.RoleDefinitions.GetByScopeAndRoleName("/", "Owner");
Good so far. The inner Rdef give me the role name, ID, and Name and now I am trying to list all users in that subscription scope for that role.
var roleassignement1 = authenticated1.RoleAssignments.ListByScopeAsync("/");// GetById("*****")// .GetByScopeAsync("subscriptions/322dac8a-416c-4de6-977c-e6b21344651c", "Owner");
What is the scope here, I added the subscription/subid as scope. What I am trying to do is list all RBAC on the subscription.
What am I doing wrong? Any pointer is appreciated.
Regards.

Just change the code from:
var roleassignement1 = authenticated1.RoleAssignments.ListByScopeAsync("/");
to
var roleassignement1 = await authenticated1.RoleAssignments.ListByScopeAsync("subscriptions/322dac8a-416c-4de6-977c-e6b21344651c");
, and then it can work.

Related

Azure authentification for multiple audience using WithExtraScopesToConsent and AcquireTokenSilent

I am building an app that let user manipulate Azure resource and Azure storage therefore I need to access multiple audiences, however, it's not possible to have one toke with multiple audience in azure. So I am using this tutorial
https://learn.microsoft.com/bs-latn-ba/azure/active-directory/develop/msal-net-user-gets-consent-for-multiple-resources
and my code look like :
IPublicClientApplication client = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
.WithDefaultRedirectUri()
// .WithRedirectUri($"msal{clientId}://auth")
.Build();
var accounts = client.GetAccountsAsync().Result;
string[] scopes = { "https://management.azure.com/user_impersonation" };
string[] scopestorage = { "https://storage.azure.com/user_impersonation" };
var result = client.AcquireTokenInteractive(scopes)
.WithAccount(accounts.FirstOrDefault())
.WithExtraScopesToConsent(scopestorage)
.ExecuteAsync().Result;
var result2= client.AcquireTokenSilent(scopestorage, accounts.FirstOrDefault()).ExecuteAsync();
but I am getting an exception while executing the AcquireTokenInteractive method
Microsoft.Identity.Client.MsalUiRequiredException: 'No account or login hint was passed to the AcquireTokenSilent call.'
Also when I look in the locals my variable "accounts" i can see Count=0 and nothing in there.
Any pointer for a solutions would be greatly appreciated.
Regards
Vincent
Your need to make some changes to your code. Here is the working sample for your reference:
string[] scopes = { "https://management.azure.com/user_impersonation" };
string[] scopestorage = { "https://storage.azure.com/user_impersonation" };
IPublicClientApplication client = PublicClientApplicationBuilder
.Create("cbc32712-ac27-4532-802d-303998a6e712")
.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
.Build();
var result = client.AcquireTokenInteractive(scopes)
.ExecuteAsync().Result;
var accounts = client.GetAccountsAsync().Result;
var result2 = client.AcquireTokenSilent(scopestorage, accounts.FirstOrDefault()).ExecuteAsync().Result;
Note:
1.As you will get access token for storage resource by using AcquireTokenSilent method, make sure you have granted user/admin consent for your application to access this resource.
2.You can not use WithExtraScopesToConsent method for different resource endpoints.

Get AccountName / UPN in a UWP App when logged on in Azure

I am creating a UWP app which shows certain data, depending on the logged on user.
The user is logged on in Windows Azure and the computer account is also joined to Azure.
I have enabled the "Account Information" feature in the app manifest.
I am trying to find out the user data, using the User Class, like mentioned in several examples online:
private async void GetAllUserData()
{
var users = await User.FindAllAsync();
foreach (var user in users)
{
var authenticationStatus = user.AuthenticationStatus;
var nonRoamableId = user.NonRoamableId;
var provider = await user.GetPropertyAsync(KnownUserProperties.ProviderName);
var accountName = await user.GetPropertyAsync(KnownUserProperties.AccountName);
var displayName = await user.GetPropertyAsync(KnownUserProperties.DisplayName);
var domainName = await user.GetPropertyAsync(KnownUserProperties.DomainName);
var principalName = await user.GetPropertyAsync(KnownUserProperties.PrincipalName);
var firstName = await user.GetPropertyAsync(KnownUserProperties.FirstName);
var guestHost = await user.GetPropertyAsync(KnownUserProperties.GuestHost);
var lastName = await user.GetPropertyAsync(KnownUserProperties.LastName);
var sessionInitiationProtocolUri = await user.GetPropertyAsync(KnownUserProperties.SessionInitiationProtocolUri);
var userType = user.Type;
}
}
The only properties I can get from the user object are:
DisplayName
AuthenticationStatus
NonRoamableId
UserType
All other properties remain empty. From my understanding, when I am logged in to Windows Azure, at least the principal name should have a value.
What am I doing wrong - or in other words - what do I have to do, to get account information?
After enabling "Enterprise Authentication" feature in my app manifest, the UPN is filled in the principalName variable.
I know, this does not the real authentication job for the application, but for my purpose it is sufficient to have the UPN, authenticated in Windows.
For more information about adding Azure authentication to an app I have found the following links:
https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-windows-store-dotnet-get-started-users
https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-native-uwp-v2/

Get Owner(s) in .NET Azure Active Directory groups

I have an email account which is a Security Group where there are few members in it. I am trying to figure out the email address of the owner of the group but I haven't been able to figure it out.
Below is the source code
ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(serviceRoot, async () => await Task.FromResult(accessToken));
var group = (Group)await activeDirectoryClient.Groups.Where(u => u.Mail == "email#domaincom").ExecuteSingleAsync();.
var groupFetcher = activeDirectoryClient.Groups.GetByObjectId(group.ObjectId);
var membersResult = groupFetcher.Members.ExecuteAsync().Result;
var ownerResult = groupFetcher.Owners.ExecuteAsync().Result;
After I execute this code, I can see the members of the Group but why ownerResult variable is always empty? How can I retrieve the owner of the group?
I am testing using the code below(Microsoft.Azure.ActiveDirectory.GraphClient with version 2.1.1)and it works well for me. Please ensure that the group have the owners assigned.
var group = (Group) client.Groups.Where(u => u.Mail == "email#domain.onmicrosoft.com").ExecuteSingleAsync().Result;
var groupFetcher = client.Groups.GetByObjectId(group.ObjectId);
//var membersResult = groupFetcher.Members.ExecuteAsync().Result;
var ownerResult = groupFetcher.Owners.ExecuteAsync().Result;
foreach (var owner in ownerResult.CurrentPage)
Console.WriteLine(((Microsoft.Azure.ActiveDirectory.GraphClient.User)owner).DisplayName);
You can check it from Azure portal like figure below:
If the owner exists, I also suggest that you capture the request using Fiddler to check whether the response is expected.

Azure AD Add AppRoleAssignment

I am using Azure AD for the authentication service on an MVC application. I am managing the user accounts successfully using the Graph API. I am trying to add an AppRoleAssignment to the user.
string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
Uri servicePointUri = new Uri(graphResourceID);
Uri serviceRoot = new Uri(servicePointUri, tenantID);
ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(serviceRoot, async () => await GetTokenForApplication());
IUser user = new User();
user.JobTitle = "Tester";
user.DisplayName = "Test Tester";
user.Surname = "Tester";
user.GivenName = "Test";
user.UserPrincipalName = "ttester#test.com";
user.AccountEnabled = true;
user.MailNickname = "ttester";
user.PasswordProfile = new PasswordProfile
{
Password = "XXXXX",
ForceChangePasswordNextLogin = true
};
await activeDirectoryClient.Users.AddUserAsync(user);
var appRoleAssignment = new AppRoleAssignment
{
Id = Guid.Parse("XXXXX"),
ResourceId = Guid.Parse("XXXXX"),
PrincipalType = "User",
PrincipalId = Guid.Parse(user.ObjectId)
};
user.AppRoleAssignments.Add(appRoleAssignment);
await user.UpdateAsync();
The AppRoleAssignment is never made. I am not certain if it is the constructor variables.
The id I am placing the ID of the role, being created in the application manifest. The ResourceId I am placing the ObjectId of the application. The application is created under the AAD Directory.
The code actually completes without error, however inspecting the user it shows not AppRoleAssignments.
In the end I am trying to implement RBAC using application roles.
Any help is greatly appreciated.
To assign application role to a user, you need to cast the User object to IUserFetcher:
await ((IUserFetcher)user)
.AppRoleAssignments.AddAppRoleAssignmentAsync(appRoleAssignment);
I also had to set the ResourceId to the ServicePrincipal.ObjectId
var servicePrincipal = (await
activeDirectoryClient.ServicePrincipals.Where(
s => s.DisplayName == "MyApplicationName").ExecuteAsync()).CurrentPage
.First();
var appRoleAssignment = new AppRoleAssignment
{
Id = Guid.Parse("XXXXX"),
// Service principal id go here
ResourceId = Guid.Parse(servicePrincipal.ObjectId),
PrincipalType = "User",
PrincipalId = Guid.Parse(user.ObjectId)
};

Error:InvalidAuthenticationTokenTenant' The access token is from the wrong issuer

I am using Node js to authenticate into Azure AD to create a Data lake storage account, it logs in but for the account creation it gives the error: code: 'InvalidAuthenticationTokenTenant',
message: 'The access token is from the wrong issuer \'https://sts.windows.n
et\'. It must match the tenant \'https://sts.windows.net/\' associated with this subs
cription.
var msRestAzure = require('ms-rest-azure');
var adlsManagement = require("azure-arm-datalake-store");
msRestAzure.interactiveLogin(function(err, credentials) {
var accountName = 'testadlsacct';
var pathToEnumerate = '/myfolder';
var acccountClient = new adlsManagement.DataLakeStoreAccountClient(credentials, 'dxxxxxxx-dxxx-4xxx-bxxx-5xxxxxxxxx');
var filesystemClient = new adlsManagement.DataLakeStoreFileSystemClient(credentials);
var util = require('util');
var resourceGroupName = 'testrg';
var accountName = 'testadlsacct';
var location = 'eastus2';
var accountToCreate = {
tags: {
testtag1: 'testvalue1',
testtag2: 'testvalue2'
},
name: accountName,
location: location
};
var client= new adlsManagement.DataLakeStoreAccountClient(credentials, 'dxxxxxxxx-xxx-xxxx--xxxxxx');
client.account.create(resourceGroupName, accountName, accountToCreate, function (err, result, request, response)
//other code here
});
Taking a look at how ms-rest-azure's msRestAzure.interactiveLogin function is written, it appears that there's a "domain", or tenant, parameter that you can pass in the event that you are a member of more than one Azure Active Directory (tenant).
You should pass in the tenant that is tied to your subscription. This should be given to you in the full, current error message that you get. The tenant may look like "contoso.com", "contoso.onmicrosoft.com", or it could be a GUID.
This disambiguates your authentication call by explicitly mentioning which directory should be used.
I hope this helps!

Resources