使用Azure AD Graph客户端API

时间:2016-05-17 17:56:15

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

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

2 个答案:

答案 0 :(得分:2)

您需要确保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类型。然后我传递了一个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,我在获取用户令牌时也会捕获AADSTS50126异常,因为这表示获取令牌时凭据无效。

答案 1 :(得分:0)

仅当您授予应用程序正确的权限时,才可以从应用程序中更改密码。 如果您可以模拟用户(当然,该用户当然有权更改其密码),则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)来更改其他用户的密码。