I am trying to create a page in ASP.Net MVC to reset the current user\'s password. I am using Azure active directory for user authentication. To access, the user\'s AD informa
You can change the password from your application only if you give to it the right privilege. The approach explained by Martyn C is the best approach if you can impersonate the user, which, of course, has the permission to change his password. With my approach there's no need to use any UserCredentials since the permissions will be assigned to the application that will be able to change the password for other users. A typical use case is when you need to manage password change from api with a non-interactive flow. This implies you must trust the application's code and use it carefully.
I used to grant the Helpdesk Administrator role to my app which is enough to change password to other users. Through this powershell script:
Install-Module MSOnline
Install-Module AzureAD
Connect-MsolService
Connect-AzureAD
$applicationId = "{your app ID}"
$sp = Get-MsolServicePrincipal -AppPrincipalId $applicationId
Add-MsolRoleMember -RoleObjectId <your Role ID> -RoleMemberObjectId $sp.ObjectId -RoleMemberType servicePrincipal
You should connect using a User with Administrator Privileges on your Active Directory. You can get the propert roleID using this command:
Get-AzureADDirectoryRole
Now your app has enough privileges to call the PATCH method (from Microsoft Docs) to change the password for other users.
You need to ensure that your application configuration in Azure Active Directory has the appropriate permissions setup. Adding the rights using what you have above is overkill. You should be adding the required permissions only to your application in the directory.
As a starting point I would suggest you review the Graph API Consent Permission blog post here. You can only reset a password as an account or global administrator using traditional rights but you should be assigning application permissions.
"Read and write directory data" used to provide this permission however I believe this was removed. Now I believe the user has to consent using the OAuth authentication flow to be able to reset a password.
See the changePassword method on the currently logged in user for more information on this. I have a custom desktop application for users to reset their own passwords.
In my application I have the users authenticate to get an access token using their existing password (this also helps me validate their current credentials before changing the password).
var authority = string.Format(CultureInfo.InvariantCulture, "https://login.microsoftonline.com/" + Domain);
var ctx = new AuthenticationContext(authority, false);
var result = ctx.AcquireToken("https://graph.windows.net", "ClientID", credential);
return result.AccessToken;
The credential property is a UserCredential
type using the users UPN and password. I then pass a web request to change the password.
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", UserAccessToken);
var requestUri = $"https://graph.windows.net/me/changePassword?api-version={Constants.ApiVersion}";
var pwdObject = new { currentPassword = curPassword, newPassword = newPass };
var body = new JavaScriptSerializer().Serialize(pwdObject);
var response = client.PostAsync(new Uri(requestUri), new StringContent(body, Encoding.UTF8, "application/json")).Result;
This returns a HTTP 204 if the request was successful, I also trap a AADSTS50126 exception when getting the user token as this indicates the credentials are invalid when obtaining the token.