MSGraph SDK: How to show expiring secrets?

Jeff Bowman 101 Reputation points
2023-05-26T22:00:02.12+00:00

I'm able to connect and get the Service Principal I need, but its PasswordCredentials list is empty even though a Client Secret is configured in the portal. In fact, ALL principals have empty PasswordCredential lists—the CredentialAction shown below is never invoked.

I'm authenticating as the tenant's Global Admin.

Am I missing something somewhere? Here's my code:

Private Async Function ShowExpiringSecrets() As Task
  Dim oCredentialAction As Action(Of PasswordCredential)
  Dim oPrincipalAction As Action(Of ServicePrincipal)
  Dim oGraphClient As GraphServiceClient
  Dim oPrincipals As List(Of ServicePrincipal)
  Dim oCredential As DefaultAzureCredential
  Dim oResponse As ServicePrincipalCollectionResponse
  Dim oOptions As TokenCredentialOptions
  Dim aScopes As String()

  aScopes = New String() {$"{My.Resources.MsGraphEndPoint}.default"}
  oOptions = New TokenCredentialOptions With {.AuthorityHost = AzureAuthorityHosts.AzurePublicCloud}
  oCredential = New DefaultAzureCredential
  oGraphClient = New GraphServiceClient(oCredential, aScopes)
  oResponse = Await oGraphClient.ServicePrincipals.GetAsync

  oCredentialAction = Sub(Credential)
                        If Credential.EndDateTime < Date.UtcNow.AddDays(30) Then
                          Console.WriteLine($"{Credential.DisplayName} - {Credential.EndDateTime}")
                        End If
                      End Sub

  oPrincipalAction = Sub(Principal) Principal.PasswordCredentials.ForEach(oCredentialAction)
  oPrincipals = oResponse.Value.OrderBy(Function(Principal) Principal.DisplayName).ToList

  oPrincipals.ForEach(oPrincipalAction)
End Function

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
10,674 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Jeff Bowman 101 Reputation points
    2023-05-27T01:05:13.1666667+00:00

    It turns out we need to get Applications, not ServicePrincipals.

    Private Async Function ShowExpiringSecrets() As Task
      Dim oGraphClient As GraphServiceClient
      Dim oCredential As DefaultAzureCredential
      Dim oResponse As ApplicationCollectionResponse
      Dim oSecret As PasswordCredential
      Dim oApps As List(Of Application)
      Dim oApp As Application
    
      oCredential = New DefaultAzureCredential
      oGraphClient = New GraphServiceClient(oCredential)
      oResponse = Await oGraphClient.Applications.GetAsync
      oApps = oResponse.Value.OrderBy(Function(Application) Application.DisplayName).ToList
    
      For Each oApp In oApps
        For Each oSecret In oApp.PasswordCredentials
          Console.WriteLine($"{oApp.DisplayName} - {oSecret.EndDateTime}")
        Next
      Next
    End Function
    

    This works. YMMV.

    0 comments No comments