Reputation: 3788
I have cloned the MS Identity DotNetCore B2C Account Management code sample and configured it for my B2C tenant. The get user and delete user commands all work. However when I try to use command [5] Update user password
I encounter this error:
Code: Authorization_RequestDenied Message: Insufficient privileges to complete the operation.
The description of this Microsoft support issue for Office 365 seems to overlap with what I'm encountering. The implication seems to be that an admin account is at a higher level than the application can touch because the application isn't an admin within AD.
So, the application could manage normal non-admin users, but not admin accounts? Am I understanding that correctly. And if so is there a way to elevate my registered application's privileges so as to update passwords for admins as well as non-admin accounts?
The only changes to the sample were in appsettings.json
and entailed the expected customization of values for "TenantId"
, "AppId"
, and "ClientSecret"
.
I've registered an application and granted the following permissions for Graph API:
This is the code attempting the user password update:
public static async Task SetPasswordByUserId(GraphServiceClient graphClient)
{
Console.Write("Enter user object ID: ");
string userId = Console.ReadLine();
Console.Write("Enter new password: ");
string password = Console.ReadLine();
Console.WriteLine($"Looking for user with object ID '{userId}'...");
var user = new User
{
PasswordPolicies = "DisablePasswordExpiration,DisableStrongPassword",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = false,
Password = password,
}
};
try
{
// Update user by object ID
await graphClient.Users[userId]
.Request()
.UpdateAsync(user);
Console.WriteLine($"User with object ID '{userId}' successfully updated.");
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(ex.Message);
Console.ResetColor();
}
}
Upvotes: 0
Views: 886
Reputation: 42063
To update the passwordProfile
of the user, the Directory.AccessAsUser.All
permission is needed.
See the doc:
And you should note the Directory.AccessAsUser.All
is the Delegated permission
, not Application permission
. It means the permission will not take effect in the client credential flow(the sample you provided uses it), so when you use the Microsoft Graph SDK, you could not use the Client credentials provider
, your option is to use the Authorization code provider
(recommended).
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithRedirectUri(redirectUri)
.WithClientSecret(clientSecret) // or .WithCertificate(certificate)
.Build();
AuthorizationCodeProvider authProvider = new AuthorizationCodeProvider(confidentialClientApplication, scopes);
Upvotes: 1