【问题标题】:Permission issue changing user password using Azure AD Graph client API使用 Azure AD Graph 客户端 API 更改用户密码的权限问题
【发布时间】:2016-09-13 23:20:25
【问题描述】:

我正在尝试在 ASP.Net MVC 中创建一个页面来重置当前用户的密码。我正在使用 Azure 活动目录进行用户身份验证。要访问用户的 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 变量设置为什么值?

【问题讨论】:

    标签: c# azure permissions azure-active-directory


    【解决方案1】:

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

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

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

    查看当前登录用户的changePassword 方法以获取更多信息。我有一个自定义桌面应用程序供用户重置自己的密码。

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

    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 类型。然后我通过网络请求更改密码。

    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,我在获取用户令牌时也会捕获 AADSTS50126 异常,因为这表明在获取令牌时凭据无效。

    【讨论】:

    • 您能否详细说明如何创建 UserCredential?我看到的唯一属性和构造函数是用户名。桌面应用程序库和网络应用程序库有区别吗?
    • 我不相信存在差异,这里有一些关于使用UserCredential的信息... cloudidentity.com/blog/2014/07/08/… 虽然基本用法是... var credential = new UserCredential("username","password");
    • 由于某种原因,UserCredential 没有两个构造函数,但 UserPasswordCredential 可以解决问题。在调整了我的常量和权限之后,我让它工作了。谢谢。
    • 不用担心,我相信 UserCredential 在 Microsoft.IdentityModel.Clients.ActiveDirectory 中,它是几个不同命名空间的成员。
    【解决方案2】:

    只有在您授予应用程序正确的权限后,您才能从应用程序中更改密码。 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 <your Role ID> -RoleMemberObjectId $sp.ObjectId -RoleMemberType servicePrincipal
    

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

    Get-AzureADDirectoryRole
    

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

    【讨论】:

      猜你喜欢
      • 2018-01-16
      • 1970-01-01
      • 2016-08-20
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多