使用Azure AD Graph客户端API更改用户密码的权限问题

我试图在ASP.Net MVC中创建一个页面来重置当前用户的密码。 我使用Azure Active Directory进行用户身份validation。 要访问用户的AD信息,我使用的是C#Graph API客户端。 我的代码基于GitHub上的示例

我可以更改用户的信息(例如城市,州,电子邮件)。 但是,当我尝试使用用户对象上的PasswordProfile属性更改密码时,我收到一条错误消息,指出我没有足够的权限。 我试图将密码更改为应用程序,我相信权限问题的来源是应用程序。

我找到了以下PowerShell脚本,该脚本应该将公司管理员角色添加到应用程序中。 但是,对Get-MsolServicePrincipal的调用不会返回任何内容。 查看命令的输出,我没有看到任何类似于我的应用程序名称的条目。

#----------------------------------------------------------- # This will prompt you for your tenant's credential # You should be able to use your your Azure AD administrative user name # (in the admin@tenant.onmicrosoft.com format) #----------------------------------------------------------- import-module MSOnline Connect-MsolService #----------------------------------------------------------- # Replace the Application Name with the name of your # Application Service Principal #----------------------------------------------------------- $displayName = "My Azure AD Application" $objectId = (Get-MsolServicePrincipal -SearchString $displayName).ObjectId #----------------------------------------------------------- # This will add your Application Service Prinicpal to # the Company Administrator role #----------------------------------------------------------- $roleName = "Company Administrator" Add-MsolRoleMember -RoleName $roleName -RoleMemberType ServicePrincipal -RoleMemberObjectId $objectId 

我想我的第一个问题是我是否认为许可问题与申请有关?

第二,我应该设置$ displayName变量的值是多少?

您需要确保Azure Active Directory中的应用程序配置具有适当的权限设置。 使用上面的内容添加权限是过度的。 您应该只将所需权限添加到目录中的应用程序。

作为起点,我建议您在此处查看Graph API Consent Permission博客文章。 您只能使用传统权限将密码重置为帐户或全局管理员,但您应该分配应用程序权限。

“读取和写入目录数据”用于提供此权限,但我相信这已被删除。 现在我相信用户必须同意使用OAuth身份validation流程才能重置密码。

有关详细信息,请参阅当前登录用户的changePassword方法。 我有一个自定义桌面应用程序供用户重置自己的密码。

在我的应用程序中,我让用户进行身份validation以使用现有密码获取访问令牌(这也有助于我在更改密码之前validation其当前凭据)。

 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; 

凭证属性是使用用户UPN和密码的UserCredential类型。 然后我传递一个Web请求来更改密码。

 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; 

如果请求成功,则返回HTTP 204,我还在获取用户令牌时捕获AADSTS50126exception,因为这表示获取令牌时凭据无效。

只有在为其提供了正确的权限时,才能从应用程序更改密码。 如果您可以冒充用户,那么Martyn C解释的方法是最好的方法,当然,用户有权更改密码。 使用我的方法,不需要使用任何UserCredentials,因为权限将分配给能够更改其他用户密码的应用程序。 一个典型的用例是当您需要使用非交互流来管理来自api的密码更改时。 这意味着您必须信任应用程序的代码并仔细使用它。

我曾经将帮助台管理员角色授予我的应用程序,这足以将密码更改为其他用户。 通过这个powershell脚本:

 Install-Module MSOnline Install-Module AzureAD Connect-MsolService Connect-AzureAD $applicationId = "{your app ID}" $sp = Get-MsolServicePrincipal -AppPrincipalId $applicationId Add-MsolRoleMember -RoleObjectId  -RoleMemberObjectId $sp.ObjectId -RoleMemberType servicePrincipal 

您应该使用Active Directory上的具有管理员权限的用户进行连接。 您可以使用以下命令获取属性roleID:

 Get-AzureADDirectoryRole 

现在,您的应用程序具有足够的权限来调用PATCH方法(来自Microsoft Docs )来更改其他用户的密码。