The Graph Client Authentication Providers allows for each authentication to the graph endpoint implementing a variety of OAUTH2 flows.  I will demonstrate the use of this library in c# code based on this GitHub. Previously, you had to build your own Authentication Provider ( see my creation of the client credentials provider in a vb.net application here ) .  This library will allow you to use the following flows:

  • Confidential Client Providers
    • Authorization code
    • Client Credentials
    • On behalf of
  • Public Client Providers
    • Device Code
    • Integrated windows authentication
    • Interactive Authentication ( This blog demonstrates this flow )

The GitHub readme does show all those basic flow implementations.

Note: The library is in preview release only and is subject to change without notice.

I used the same app registration I created demonstrating how to use MSAL here.

Start a new c# console application and install the following Nuget Packages.

Nuget Packages

  • Microsoft.Graph – Also installs:
    • Microsoft.Graph.Core
    • Newtonsoft.Json
    • System.Buffers
    • System.Diagnostics.DiagnosticSource
    • System.Memory
    • System.Numerics.Vectors
    • System.Runtime.CompilerServices.Unsafe
    • System.ValueTuple
  • Microsoft.Graph.Auth ( Preview Version – you must check the “Include Prerelease” box to find ) – Also installs:
    • System.Security.Principal
    • Microsoft.identity.Client

I only have one code file – Program.cs ( the default code file for a console app ).  Here is the code:

using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Identity.Client;
using System;
using System.Threading.Tasks;

namespace GraphClient
{
    class Program
    {
        static String client_id = "{client_id}";
        static String tenant_id = "{tenant_id}";
        static String[] scopes = { "https://graph.microsoft.com/.default" };

        static IPublicClientApplication _pca = null;
        private static IPublicClientApplication Pca
        {
            get
            {
                if(_pca == null )
                {
                    _pca = PublicClientApplicationBuilder
                        .Create( client_id )
                        .WithTenantId( tenant_id )
                        .Build();
                }

                return _pca;
            }
        }

        static InteractiveAuthenticationProvider _authProvider = null;
        private static InteractiveAuthenticationProvider AuthProvider
        {
            get
            {
                if(_authProvider == null )
                {
                    _authProvider = new InteractiveAuthenticationProvider( Pca, scopes );
                }
                return _authProvider;
            }
        }

        static GraphServiceClient _graphClient = null;
        private static GraphServiceClient GraphClient
        {
            get
            {
                if(_graphClient == null )
                {
                    _graphClient = new GraphServiceClient( AuthProvider );
                }
                return _graphClient;
            }
        }

        static void Main(string[] args)
        {
            Get_Me().Wait();

            Console.WriteLine( $"\nPress any key to close..." );
            Console.ReadKey();
        }

        static async Task Get_Me()
        {
            User user = null;

            user = await GraphClient.Me.Request().GetAsync();

            Console.WriteLine( $"Display Name = {user.DisplayName}\nEmail = {user.Mail}" );
        }
    }
}

 

To implement one of the other flows, you may be modifying the Client type ( line 15 in the code file above ) based on whether or not it is a confidential client or a public client ( see list at the beginning of this post ) and the property for it just below, and line 39 ( code file above) where we are setting the auth provider as well as the underlying member for that. So, for example, a confidential client using the client credentials flow would look like this in the same code file:

        static String client_id = "{client_id}";
        static String tenant_id = "{tenant_id}";
        static String client_secret = "{client_secret}";
        static String[] scopes = { "https://graph.microsoft.com/.default" };
        static IConfidentialClientApplication _pca = null;
        private static IConfidentialClientApplication Pca
        {
            get
            {
                if(_pca == null )
                {
                    _pca = ConfidentialClientApplicationBuilder
                        .Create( client_id )
                        .WithTenantId( tenant_id )
                        .WithClientSecret( client_secret )
                        .Build();
                }
                return _pca;
            }
        }
        static ClientCredentialProvider _authProvider = null;
        private static ClientCredentialProvider AuthProvider
        {
            get
            {
                if(_authProvider == null )
                {
                    _authProvider = new ClientCredentialProvider( Pca );
                }
                return _authProvider;
            }
        }

 

2 Thoughts to “Graph Client Authentication Provider”

  1. Devin Tate

    When I run this code, with the alternate client type I get: Message: /me request is only valid with delegated authentication flow. Which I think makes sense because you don’t have a user you have the application.

Leave a Comment