This blog post is an extension to my previous post about how to get secrets and access tokens using Managed Identities with VB.Net and C#. You can read that post here<\/a>. There is a c# sample for this particular blog here<\/a>. The scenario here is that you already have the code to use the managed identities and now you want to get an access token for a resource that requires it have a roles claim for permissions in the access token. For example, the code for the previous post is getting an access token for Azure SQL, which does not require any permissions in the token as the token is only used to identify the user ( in this case, a managed identity ) and the aud claim to verify it is for that resource. So, lets see what changes we need to make to get an access token for Microsoft Graph that requires the permission “User.Read.All” to be able to list users in the tenant.<\/p>\n\n\n\n
# CONFIGURATION\n\n# Your tenant id (in Azure Portal, under Azure Active Directory -> Overview )\n$TenantID = \"{your tenant id}\"\n\n# Name of the manage identity (same as the Logic App name)\n$DisplayNameOfApp = \"{your managed identity name}\" \n\n# Check the Microsoft Graph documentation for the permission you need for the operation\n$Permissions = @(\"User.Read.All\")\n \n# MAIN SCRIPT\n\n# Microsoft Graph App ID\n$MSGraphAppId = \"00000003-0000-0000-c000-000000000000\"\n\n# Uncomment the next line if you need to Install the module (You need admin on the machine)\n# Install-Module Microsoft.Graph\nConnect-MgGraph -TenantId $TenantID -scopes Application.ReadWrite.All\n\n# Get the application we want to modify\n$sp = (Get-MgServicePrincipal -Filter \"displayName eq '$DisplayNameOfApp'\")\n \n# If assigning MS Graph Permissions\n$GraphServicePrincipal = Get-MgServicePrincipal -Filter \"appId eq '$MSGraphAppId'\"\n \n# Add permissions\nforeach($permission in $Permissions)\n{\n $AppRole = $GraphServicePrincipal.AppRoles | Where-Object {$_.Value -eq $permission -and $_.AllowedMemberTypes -contains \"Application\"}\n\n New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.Id -PrincipalId $sp.Id -ResourceId $GraphServicePrincipal.Id -AppRoleId $AppRole.Id\n}\n\n\n<# Remove permissions - this portion of the script show how to remove those same permissions\n$AppRoleAssignments = Get-MgServiceAppRoleAssignedTo -ObjectId $sp.ObjectId\n\nforeach($permission in $Permissions)\n{\n\n $AppRole = $GraphServicePrincipal.AppRoles | Where-Object {$_.Value -eq $permission -and $_.AllowedMemberTypes -contains \"Application\"}\n\n foreach($AppRoleAssignment in $AppRoleAssignments)\n\t{\n\t\tif($AppRole.Id -eq $AppRoleAssignment.Id) {\n\t\t\tRemove-MgServiceAppRoleAssignment -ObjectId $sp.ObjectId -AppRoleAssignmentId $AppRoleAssignment.objectid\n\t\t}\n\t\t\n\t}\n}\n#>\n\n<\/pre>\n\n\n\nThank you to Will Fiddes<\/a> for the PowerShell script!<\/p>\n\n\n\n
AccessToken at = credential.GetToken(new TokenRequestContext(new string[] { \"https:\/\/graph.microsoft.com\" }));<\/pre>\n\n\n\nDim at As AccessToken = credential.GetToken(New TokenRequestContext(New String() {\"https:\/\/graph.microsoft.com\"}))<\/pre>\n\n\n\nNow, this is just showing how to get an access token for a resource such as Microsoft Graph. However, when using the Graph service client in code, you do not need to specify the resource as the graph service client will be handling that for you. In the VB.Net code, you will need to add the Microsoft.Graph nuget package and then add the Imports Microsoft.Graph at the top of the code file.<\/p>\n\n\n\n
Sub Main()\n\n Do While True\n Get_AccessToken_With_UserAssigned_MSI()\n Make_GraphRequest_withUserMSI_Token()\n Get_Secret_With_UserAssigned_MSI()\n\n Get_AccessToken_With_SystemAssigned_MSI()\n Get_Secret_With_SystemAssigned_MSI()\n Make_GraphRequest_withSystemMSI_Token()\n\n Console.WriteLine(\"Press Enter to try again or any other key to exit\")\n Dim key As ConsoleKeyInfo = Console.ReadKey()\n\n If Not key.Key = ConsoleKey.Enter Then\n Return\n End If\n Loop\n\n\n End Sub\n\n Sub Get_AccessToken_With_UserAssigned_MSI()\n Console.WriteLine($\"Getting access token with user assigned msi:\")\n\n Dim credential As New ManagedIdentityCredential(userAssignedClientId)\n\n Dim at As AccessToken = credential.GetToken(New TokenRequestContext(New String() {\"https:\/\/graph.microsoft.com\"}))\n Dim accessToken As String = at.Token.ToString()\n Console.WriteLine($\"Access Token = {accessToken}\")\n\n End Sub\n\n Sub Make_GraphRequest_withUserMSI_Token()\n Console.WriteLine($\"Making graph request with User MSI Token:\")\n\n Dim credential As New ManagedIdentityCredential(userAssignedClientId)\n\n Dim graphClient As New GraphServiceClient(credential)\n\n Dim users As IGraphServiceUsersCollectionPage\n Try\n users = graphClient.Users().Request.GetAsync().Result\n Console.WriteLine($\"Number of users in tenant: {users.Count}{vbCrLf}\")\n Catch ex As Exception\n Console.WriteLine($\"Exception: {ex.Message}\")\n End Try\n\n\n End Sub\n\n Sub Get_AccessToken_With_SystemAssigned_MSI()\n Console.WriteLine($\"Getting access token with system assigned msi:\")\n\n Dim credential As New ManagedIdentityCredential()\n Dim at As AccessToken = credential.GetToken(New TokenRequestContext(New String() {\"https:\/\/graph.microsoft.com\"}))\n\n Dim accessToken As String = at.Token.ToString()\n Console.WriteLine($\"Access Token = {accessToken}\")\n End Sub\n\n Sub Make_GraphRequest_withSystemMSI_Token()\n Console.WriteLine($\"Making graph request with system MSI token:\")\n\n Dim credential As New ManagedIdentityCredential()\n\n Dim graphClient As New GraphServiceClient(credential)\n\n Dim users As IGraphServiceUsersCollectionPage\n Try\n users = graphClient.Users().Request.GetAsync().Result\n Console.WriteLine($\"Number of users in tenant: {users.Count}{vbCrLf}\")\n Catch ex As Exception\n Console.WriteLine($\"Exception: {ex.Message}\")\n End Try\n\n\n End Sub<\/pre>\n\n\n\nSimilar, the missing code snippets for the C# project:<\/p>\n\n\n\n
static void Main(string[] args)\n {\n while (true)\n {\n Console.Clear();\n\n Get_AccessToken_With_UserAssigned_MSI();\n Get_Secret_With_UserAssigned_MSI();\n Make_GraphRequest_With_UserMSI_Token();\n\n Get_AccessToken_With_SystemAssigned_MSI();\n Get_Secret_With_SystemAssigned_MSI();\n Make_GraphRequest_With_SystemMSI_Token();\n\n Console.WriteLine(\"Press Enter to try again or any other key to exit\");\n ConsoleKeyInfo key = Console.ReadKey();\n if (key.Key != ConsoleKey.Enter)\n {\n return;\n }\n }\n\n }\n\n static void Get_AccessToken_With_UserAssigned_MSI()\n {\n Console.WriteLine($\"Getting access token with user assigned msi:\");\n\n ManagedIdentityCredential credential = new ManagedIdentityCredential(userAssignedClientId);\n\n AccessToken at = credential.GetToken(new TokenRequestContext(new string[] { \"https:\/\/database.windows.net\" }));\n string accessToken = at.Token;\n\n Console.WriteLine($\"Access Token = {accessToken}\");\n\n }\n\n static void Get_AccessToken_With_SystemAssigned_MSI()\n {\n Console.WriteLine($\"Getting access token with system assigned msi:\");\n\n ManagedIdentityCredential credentail = new ManagedIdentityCredential();\n\n AccessToken at = credentail.GetToken(new TokenRequestContext(new string[] { \"https:\/\/database.windows.net\" }));\n string accessToken = at.Token;\n\n Console.WriteLine($\"Access token = {accessToken}\");\n\n }\n\n static void Make_GraphRequest_With_UserMSI_Token()\n {\n Console.WriteLine($\"Making graph request with User MSI Token:\");\n\n ManagedIdentityCredential credential = new ManagedIdentityCredential(userAssignedClientId);\n GraphServiceClient graphClient = new GraphServiceClient(credential);\n\n IGraphServiceUsersCollectionPage users;\n\n try\n {\n users = graphClient.Users.Request().GetAsync().Result;\n Console.WriteLine($\"Number of users in tenant: {users.Count}\\n\");\n } catch(Exception ex)\n {\n Console.WriteLine($\"\\nException: {ex.InnerException.Message}\");\n }\n\n }\n\n static void Make_GraphRequest_With_SystemMSI_Token()\n {\n Console.WriteLine($\"Making graph request with system MSI Token:\");\n\n ManagedIdentityCredential credential = new ManagedIdentityCredential();\n GraphServiceClient graphClient = new GraphServiceClient(credential);\n\n IGraphServiceUsersCollectionPage users;\n\n try\n {\n users = graphClient.Users.Request().GetAsync().Result;\n Console.WriteLine($\"Number of users in tenant: {users.Count}\\n\");\n }\n catch (Exception ex)\n {\n Console.WriteLine($\"\\nException: {ex.InnerException.Message}\");\n }\n }\n<\/pre>\n\n\n\nDownload the projects from my GitHub ( link on the previous post ) and once those are running properly, you can then add the missing pieces here for both the VB.Net project and the C# project. Remember, you will need to run the powershell script for both the User Assigned Managed Identity as well as the System Assigned Managed identity, using the names for those identities.<\/p>\n","protected":false},"excerpt":{"rendered":"
This blog post is an extension to my previous post about how to get secrets and access tokens using Managed Identities with VB.Net and C#. You can read that post here. There is a c# sample for this particular blog here. The scenario here is that you already have the code to use the managed identities and now you want to get an access token for a resource that requires…<\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,10,11,12,154,225],"tags":[299,298,187],"class_list":["post-9111","post","type-post","status-publish","format-standard","hentry","category-key-vault","category-microsoftgraph","category-ms-graph-client","category-msi","category-permissions","category-powershell","tag-managed-identity","tag-ms-graph","tag-vb-net"],"_links":{"self":[{"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/posts\/9111"}],"collection":[{"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/comments?post=9111"}],"version-history":[{"count":18,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/posts\/9111\/revisions"}],"predecessor-version":[{"id":9138,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/posts\/9111\/revisions\/9138"}],"wp:attachment":[{"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/media?parent=9111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/categories?post=9111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.aaddevsup.xyz\/wp-json\/wp\/v2\/tags?post=9111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}