I have an ASP.NET Core 7.0 Web API application which exposes a REST API for user login. I have several active user accounts in Azure AD, and I want to sign in to AD using this API.
For this purpose, I am using the NuGet package Microsoft.IdentityModel.Clients.ActiveDirectory
, version 5.3.0.
This is my code for signing in:
string clientId = Configuration.GetSection("ClientId").Value;
string domain = Configuration.GetSection("TokenEndpoint").Value;
string[] scopes = { "User.ReadWrite.All" };
IPublicClientApplication app;
app = PublicClientApplicationBuilder.Create(clientId).WithAuthority(domain).Build();
try
{
var result = await app.AcquireTokenByUsernamePassword(scopes, userData.email, userData.Password).ExecuteAsync();
return result;
}
catch (MsalException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
if(ex.InnerException != null){
Console.WriteLine(ex.InnerException.Message);
Console.WriteLine(ex.InnerException.StackTrace);
}
throw ex;
}
However, this code is returning the following error:
{
"error":"invalid_grant",
"error_description":"AADSTS65001: The user or administrator has not consented to use the application with ID '******' named '******'. Send an interactive authorization request for this user and resource. Trace ID: ****** Correlation ID: ****** Timestamp: 2024-02-12 08:34:04Z",
"error_codes":[
65001
],
"timestamp":"2024-02-12 08:34:04Z",
"trace_id":"******",
"correlation_id":"******",
"suberror":"consent_required"
}
I checked the following resources online:
Based on the suggestions made in these resources, I made the following changes
Can you please provide any clue regarding this error?
Note that the Microsoft.IdentityModel.Clients.ActiveDirectory
library calls the Azure AD Graph API which is deprecated.
Alternatively, you can use the Microsoft.Identity.Client
package for generating access token which calls Microsoft Graph API.
The error occurred because you are using permissions of the Application type with a username/password flow. Make sure to grant permissions of the Delegated type while using delegated flows like username/password flow, auth code flow, etc.
You can register an Entra ID application and grant the User.ReadWrite.All
permission of the Delegated type like this:
To generate the access token via a username/password flow, I ran the below C# code after installing the Microsoft.Identity.Client
package:
using Microsoft.Identity.Client;
namespace Sri
{
class Program
{
static async Task Main(string[] args)
{
string clientId = "appId";
string domain = "https://login.microsoftonline.com/tenantId/oauth2/v2.0/authorize";
string[] scopes = { "User.ReadWrite.All" };
IPublicClientApplication app;
app = PublicClientApplicationBuilder.Create(clientId).WithAuthority(domain).Build();
try
{
UserData userData = new UserData { email = "[email protected]", Password = "xxxxxxxxx" };
var result = await app.AcquireTokenByUsernamePassword(scopes, userData.email, userData.Password).ExecuteAsync();
Console.WriteLine("Token acquired successfully.");
Console.WriteLine($"Access Token: {result.AccessToken}");
}
catch (MsalException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
if (ex.InnerException != null)
{
Console.WriteLine(ex.InnerException.Message);
Console.WriteLine(ex.InnerException.StackTrace);
}
throw ex;
}
}
}
public class UserData
{
public string email { get; set; }
public string Password { get; set; }
}
}
Response:
To confirm that, you can decode this token by pasting it into the jwt.ms website and check whether aud
& scp
claims have valid values or not:
Now you can use this token to make Microsoft Graph API requests like listing, creating, updating and deleting Azure AD users.