Changing user password in Azure AD using GraphAPI


The following pertains to a very specific scenario:

  1. You use Azure AD for some applications (e.g. Office365), but...
  2. ...one of your applications does NOT use Azure AD (yet). It has its own authentication store and method (e.g. forms authn).
  3. However, you want to keep the application's credentials in sync with AAD. Basically, allow same signon (not single signon) to both your application and AAD managed applications. You want to keep username/pwds in-sync between your application and AAD. You want to ensure that whenever the user changes his/her password in the custom store, it is also changed in Azure AD.

To implement this, I have registered the application in Azure AD as a Native Application (not a Web App). This allows me to use the OAuth2 Resource Owner flow to programmatically (no UI) sign to AAD as the user. I gave the application one permission in addition to the standard Sign in and read user profile: Access the directory as the signed-in user. The application uses a GraphAPI 1.6 version API changePassword.

Here is the code which updates Azure AD with the new password, using the user's privilege, and, if it was successful in my local identity store (an xml file - this is obviously for demo purposes only). The code assumes that the user has already signed in and that we know his/her UPN -in this case the UPN is retrieved from the ClaimsPrincipal established earlier on. The old/new passwords are retrieved from TextBox UI elements. NativeClientId is the key of the client id obtained from AAD for this application registered as a native application. By using the user's identity to update the passport I avoid having to give my application a global or password admin privilege, usually considered too high for a web application.

Update code (from an ASP.NET project) 
            var upn = ClaimsPrincipal.Current.Claims.First(c => c.Type == UPN).Value;
            var tenantId = System.Configuration.ConfigurationManager.AppSettings["ida:TenantId"];
            var authority = String.Format(CultureInfo.InvariantCulture, "https://login.microsoftonline.com/{0}", tenantId);
            var ctx = new AuthenticationContext(authority, false);
            var clientId = System.Configuration.ConfigurationManager.AppSettings["ida:NativeClientId"];
            var result = ctx.AcquireToken("https://graph.windows.net", clientId, new UserCredential(upn, _currPwd.Text));
            var client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
            ctx.TokenCache.Clear();
            var requestUri = "https://graph.windows.net/me/changePassword?api-version=1.6";
            var newPwd = new { currentPassword = _currPwd.Text, newPassword = _newPwd.Text };
            var body = JsonConvert.SerializeObject(newPwd);
            var response = client.PostAsync(new Uri(requestUri), new StringContent(body, System.Text.Encoding.UTF8, "application/json")).Result;
            if (response.IsSuccessStatusCode)
            {
                //
                // Update external file
                //
                var path = Server.MapPath("/App_Data/Users.xml");
                var doc = XDocument.Load(path);
                var userId = ClaimsPrincipal.Current.Claims.First(c => c.Type == ClaimsIdentity.DefaultNameClaimType).Value;
                var userXml = doc.Root.Elements("user").FirstOrDefault(el => el.Attribute("userId").Value == userId);
                userXml.Attribute("password").Value = _newPwd.Text;
                doc.Save(path);
                _status.Text = "Password changed";
            }
            else
                _status.Text = "Change failed. Try a more complex password.";
Comments (2)

  1. Hasnen Dawoodji says:

    Hi there, thanks for this code. I implemented you logic to update the password on Azure AD but I get a “BadRequest”. Could you please help me out. My code is a replica of yours. Am I missing any permission?

    1. SailingRock says:

      Sorry, only noticed this now. You would need to send me a copy of the request and response to AAD, say from Fiddler. Can you do that?

Skip to main content