Home > Enterprise >  Authorization_RequestDenied - Access to change password operation is denied
Authorization_RequestDenied - Access to change password operation is denied

Time:10-18

I am writing an API for user to reset self password. User is logged in an web application which calls MS Graph API.

While trying to self update password(I need to verify the current password too), I am getting below error:

code":"Authorization_RequestDenied","message":"Access to change password operation is denied."

Below is my code:

 private static async Task UpdatePassword(string clientId, string clientSecret, string tenantId)
    {
        try
        { 
            var scopes = new string[] { "https://graph.microsoft.com/.default" };

            // Configure the MSAL client as a confidential client
            var confidentialClient = ConfidentialClientApplicationBuilder
                .Create(clientId)
                .WithAuthority($"https://login.microsoftonline.com/{tenantId}/v2.0")
                .WithClientSecret(clientSecret)
                .Build();

           
            GraphServiceClient graphServiceClient =
                new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
                {

                // Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
                    var authResult = await confidentialClient
                .AcquireTokenForClient(scopes)
                .ExecuteAsync();

                // Add the access token in the Authorization header of the API request.
                    requestMessage.Headers.Authorization =
                new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
                })
                ); 

            await graphServiceClient.Users["9c704dfb-a3ea-528a-937c-d7da45ebcc7a"]
                .ChangePassword("OldPassword", "NewPassword").Request().PostAsync(); 

        }catch(Exception e)
        { 
        }
    }

I also saw /me endpoints but did not understand how to make that work in my scenario.

I appreciate any help, Thank you.

CodePudding user response:

Your requirement: Writing an API for user to reset self password.

Background: User is logged in an web application which calls MS Graph API.

If you want to create a stand alone web api which exposing a feature to let users update their password, it is impossible. Let's see the enter image description here

We can only use Delegated api permission. According to the screenshot in your enter image description here

And in your Controller, inject GraphServiceClient graphServiceClient and change password with code await graphClient.Me.ChangePassword(currentPassword,newPassword).Request().PostAsync();

CodePudding user response:

I agree with @Tiny Wang. Although I have done the same via postman and it’s just a different approach to the solution of your issue.

To change user's password, you must add Delegated Directory.AccessAsUser.All permission for your application.

Please note that, the code you mentioned is using Client credentials flow that works with only Application permissions.

I tried to reproduce the same in my environment and got below results:

I granted below API permissions to the Azure AD application in my B2C tenant:

enter image description here

Now I generated access token using client credentials flow via Postman like below:

POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
client_id:client_id
grant_type:client_credentials
client_secret:client_secret
scope:https://graph.microsoft.com/.default

Response:

enter image description here

When I used the above token to call below query, I got same error:

POST https://graph.microsoft.com/v1.0/users/signed_in_user_id/changePassword
{
"currentPassword": "xxxxxx",
"newPassword": "xxxxxxxxx"
}

Response:

enter image description here

To resolve the error, you need to use interactive flows like Authorization Code, Username Password etc...

So, I generated access token using Authorization Code flow via Postman like below:

POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
client_id:client_id
grant_type:authorization_code
scope:https://graph.microsoft.com/.default
client_secret:client_secret
code:code
redirect_uri:redirect_uri

enter image description here

When I used the above token to call below query, password changed successfully like below:

POST https://graph.microsoft.com/v1.0/users/signed_in_user_id/changePassword
{
"currentPassword": "xxxxxx",
"newPassword": "xxxxxxxxx"
}

Response:

enter image description here

Please note that, /me/changePassword endpoint is same as /users/signed_in_user_id/changePassword endpoint.

I tried using /me/changePassword endpoint and got same results as below:

enter image description here

Code sample in C#:

GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var currentPassword = "xxxxxxx";
var newPassword = "xxxxxxxxxx";
await graphClient.Me
.ChangePassword(currentPassword,newPassword)
.Request()
.PostAsync();

Reference: user: changePassword - Microsoft Graph

  • Related