I am trying to reset the password of a native AAD User using below code
HttpResponseMessage createResponse = new();
RequestBodyPwReset requestBodyPWReset = new ()
{
passwordProfile = new PasswordProfile()
{
forceChangePasswordNextSignIn = true,
password = newPassword
}
};
string jsonObj = JsonConvert.SerializeObject(requestBodyPWReset);
string uri = Constants.UrlToCreateLocalUserInAad + "/"+userAadId;
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Patch,
RequestUri = new Uri(uri),
Headers =
{
{ HttpRequestHeader.Accept.ToString(), "application/json" }
},
Content = new StringContent(jsonObj, Encoding.UTF8, "application/json")
};
httpRequestMessage.Headers.Add("Authorization", token);
try
{
createResponse = new HttpClient().Send(httpRequestMessage);
if (createResponse != null && createResponse.IsSuccessStatusCode)
{
string createResponseData = createResponse.Content.ReadAsStringAsync().Result;
return "OK";
}
else
{
return "Sorry, try again. " + createResponse.ReasonPhrase + "---------- " + createResponse.RequestMessage.ToString();
}
}
catch (Exception ex)
{
string exMsg = ex.Message ?? "";
string exInner = ex.InnerException == null ? "" : ex.InnerException.Message ?? "";
return "Sorry, try again.";
}
The json request for my code translates as below. I have obtained the access-token by using my AAD Tenant Id and Client Id of my Enterprise application. I am sending the obtained access token with the request headers to serve my purpose.
{
Method: PATCH, RequestUri: 'https://graph.microsoft.com/v1.0/users/8e91ee04-0e5d-4628-b555-f8caca9e4a27', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
Accept: application/json
Authorization: Bearer eyJ0exxxxxxxxxxxxxxxxxxxxxxxxxxxx
traceparent: 00-a7e3149c95c5f61e53c154d57eabd0cd-12e7097ec88ffaaa-00
Content-Type: application/json; charset=utf-8
Content-Length: 81
}
}
This is the response I am getting
{
StatusCode: 403, ReasonPhrase: 'Forbidden', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
Cache-Control: no-cache
Transfer-Encoding: chunked
Strict-Transport-Security: max-age=31536000
request-id: 24908338-9c31-4d96-9828-6427d7d1d938
client-request-id: 24908338-xxxx-xxxx-xxxx-6427d7d1d938
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"South India","Slice":"E","Ring":"2","ScaleUnit":"002","RoleInstance":"MA1PEPF0000273D"}}
x-ms-resource-unit: 1
Date: Thu, 06 Jul 2023 09:52:04 GMT
Content-Type: application/json
}, Trailing Headers:
{
}}
Any clues where I am going wrong or what I may do differently to achieve this ?
Your access token contains the User.ReadWrite.All
application permission, and it alone is not enough according to documentation for updating a user: https://learn.microsoft.com/en-us/graph/api/user-update?view=graph-rest-1.0&tabs=http#request-body.
Quoting from docs for passwordProfile
property:
In application-only access, the calling app must be assigned the User.ReadWrite.All application permission and at least the User Administrator Azure AD role.
So your application needs to be assigned a directory role as well. This can be done through Roles and Administrators -> User Administrator -> Add assignments.
Do note this will not be enough to reset passwords for global administrators. If you needed that, the application would need a higher role.