Microsoft Graph API Scripted Authentication

Viewed 4747

How does one authenticate as a user without any direct user interaction?


Otherwise i found a workaround with client credential flow in this example : https://github.com/microsoftgraph/console-csharp-snippets-sample but if i try to implement this code in an c# Asp.net mav applcition or a windows forms application i cant get an application token. If i debug the app it stuck at waiting for token but it doesn't throw an error (virus protection already deactivated). Does anyone have a idea for the main problem or my workaround?

This is the Code for my workaround trying to get a token, but stuck on daemonClient.AcquireTokenForClientAsync.

   public async Task<Users> GetUser(string Username)
    {
        MSALCache appTokenCache = new MSALCache(clientId);

        ClientCredential clientdummy = new ClientCredential(clientSecret);
        
        ConfidentialClientApplication daemonClient = new ConfidentialClientApplication(clientId, string.Format(AuthorityFormat, tenantId), redirectUri,
                                                            clientdummy, null, null);

        authenticate(daemonClient).Wait();

        string token = authResult.AccessToken;

        client = GetAuthenticatedClientForApp(token);

        IGraphServiceUsersCollectionPage users = client.Users.Request().GetAsync().Result;
    }

    private async Task<AuthenticationResult> authenticate(ConfidentialClientApplication daemonClient)
    {
        authResult = await daemonClient.AcquireTokenForClientAsync(new[] { MSGraphScope });
        return authResult;
    }
2 Answers

Found Workaround Solution: getting a Token via REST API. Here I can get an User token or an Client token to access to graph api:

 var client = new RestClient("https://login.microsoftonline.com/" + domainname);
 var request = new RestRequest("/oauth2/token", Method.POST);   request.AddBody("grant_type", "client_credentials");
        request.AddParameter("client_id", clientId);
        request.AddParameter("client_secret", clientSecret);
        request.AddParameter("Resource", "https://graph.microsoft.com");
        request.AddParameter("scope", "[scopes]"); 
        IRestResponse response = client.Execute(request);
        //contains the token 
        var content = response.Content;

According to your description, I assume you need a solution to authenticate a user without any interaction.

We can get an Access Token by some background services or daemons.

For more details, we can refer to this document.

Base on my test, we can try the following steps:

First, we should get administrator consent:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
                                           {
                                               ClientId = clientId,
                                               Authority = authority,
                                               RedirectUri = redirectUri,
                                               PostLogoutRedirectUri = redirectUri,
                                               Scope = "openid profile",
                                               ResponseType = "id_token",
                                               TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, NameClaimType = "name" },
                                               Notifications = new OpenIdConnectAuthenticationNotifications
                                                               {
                                                                   AuthenticationFailed = this.OnAuthenticationFailedAsync,
                                                                   SecurityTokenValidated = this.OnSecurityTokenValidatedAsync
                                                               }
                                           });



ConfidentialClientApplication daemonClient = new ConfidentialClientApplication(Startup.clientId, string.Format(AuthorityFormat, tenantId), Startup.redirectUri,
                                                                                       new ClientCredential(Startup.clientSecret), null, appTokenCache.GetMsalCacheInstance());
AuthenticationResult authResult = await daemonClient.AcquireTokenForClientAsync(new[] { MSGraphScope });

Then, we can use this access token to using the Graph APIs.

For more details, we can review to v2.0 daemon sample on GitHub.

Related