mel*_*erg 6 c# adal azure-ad-graph-api
我以前一直使用Active Directory身份验证库(ADAL)以编程方式添加用户,但是现在我需要定义“ signInNames”(=用户电子邮件),而ADAL似乎无法实现(请告诉我即时消息是否错误) 。
现在,我尝试按照MSDN上的文档以编程方式使用HTTP POST添加新用户(本地帐户)。
//Get access token (using ADAL)
var authenticationContext = new AuthenticationContext(AuthString, false);
var clientCred = new ClientCredential(ClientId, ClientSecret);
var authenticationResult = authenticationContext.AcquireTokenAsync(ResourceUrl, clientCred);
var token = authenticationResult.Result.AccessToken;
//HTTP POST CODE
const string mail = "new@email.com";
// Create a new user object.
var user = new CustomUser
{
accountEnabled = true,
country = "MS",
creationType = "LocalAccount",
displayName = mail,
passwordPolicies = "DisablePasswordExpiration,DisableStrongPassword",
passwordProfile = new passwordProfile { password = "jVPmEm)6Bh", forceChangePasswordNextLogin = true },
signInNames = new signInNames { type = "emailAddress", value = mail }
};
var url = "https://graph.windows.net/" + TenantId + "/users?api-version=1.6";
var jsonObject = JsonConvert.SerializeObject(user);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = client.PostAsync(url,
new StringContent(JsonConvert.SerializeObject(user).ToString(),
Encoding.UTF8, "application/json"))
.Result;
if (response.IsSuccessStatusCode)
{
dynamic content = JsonConvert.DeserializeObject(
response.Content.ReadAsStringAsync()
.Result);
// Access variables from the returned JSON object
var appHref = content.links.applications.href;
}
}
Run Code Online (Sandbox Code Playgroud)
但是我没有成功,得到这个回应:
{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content:....}
Run Code Online (Sandbox Code Playgroud)
有什么想法我应该做什么?我成功使用了Powershell脚本,但是我需要在C#应用程序中执行此操作。
您是否授予该应用足够的权限来操作用户?对于 B2C 租户,创建用户 REST API 对我来说效果很好。
以下是我测试的步骤:
1.通过下面的PowerShell创建应用程序
PowerShell:
$bytes = New-Object Byte[] 32
$rand = [System.Security.Cryptography.RandomNumberGenerator]::Create()
$rand.GetBytes($bytes)
$rand.Dispose()
$newClientSecret = [System.Convert]::ToBase64String($bytes)
New-MsolServicePrincipal -DisplayName "My New B2C Graph API App" -Type password -Value
Run Code Online (Sandbox Code Playgroud)
2.授予应用程序用户帐户管理员角色。
Add-MsolRoleMember -RoleObjectId fe930be7-5e62-47db-91af-98c3a49a38b1 -RoleMemberObjectId 7311370c-dac3-4f34-b2ce-b22c2a5a811e -RoleMemberType servicePrincipal
Run Code Online (Sandbox Code Playgroud)
3.使用客户端凭据流获取应用程序的令牌
POST: https://login.microsoftonline.com/adb2cfei.onmicrosoft.com/oauth2/token
grant_type=client_credentials&client_id={AppPrincipalId return by PowerShell}&client_secret={client_secret}&resource=https%3A%2F%2Fgraph.windows.net
Run Code Online (Sandbox Code Playgroud)
4.使用下面的REST创建用户:
POST: https://graph.windows.net/adb2cfei.onmicrosoft.com/users?api-version=1.6
authorization: bearer {token}
content-type: application/json
{
"accountEnabled": true,
"creationType": "LocalAccount",
"displayName": "Alex Wu",
"passwordProfile": {
"password": "Test1234",
"forceChangePasswordNextLogin": false
},
"signInNames": [
{
"type": "userName",
"value": "AlexW"
},
{
"type": "emailAddress",
"value": "AlexW@example.com"
}
]
}
Run Code Online (Sandbox Code Playgroud)
感谢您的回复 Fei Xue,我相信我有正确的权限。我做了什么来解决我的问题。
首先我删除了我自己的自定义类“NewUser”,然后我下载了这个示例项目:https : //github.com/AzureADQuickStarts/B2C-GraphAPI-DotNet/blob/master/B2CGraphClient/B2CGraphClient.cs以消除风险我的代码错了。我修改了它以支持我的需求,然后我创建了一个简单的 JObject:
var jsonObject = new JObject
{
{"accountEnabled", true},
{"country", customer.CustomerBase.Company},
{"creationType", "LocalAccount"},
{"displayName", pendingCustomer.Email.Trim()},
{"passwordPolicies", "DisablePasswordExpiration,DisableStrongPassword"},
{"passwordProfile", new JObject
{
{"password", pwd},
{"forceChangePasswordNextLogin", true}
} },
{"signInNames", new JArray
{
new JObject
{
{"value", pendingCustomer.Email.Trim()},
{"type", "emailAddress"}
}
}
}
};
client = new B2CGraphClient(ClientId, ClientSecret, TenantId);
var response = await client.CreateUser(jsonObject.ToString());
var newUser = JsonConvert.DeserializeObject<User>(response);
Run Code Online (Sandbox Code Playgroud)
来自 B2CGraphClient.cs
private async Task<string> SendGraphPostRequest(string api, string json)
{
// NOTE: This client uses ADAL v2, not ADAL v4
var result = authContext.AcquireToken(Globals.aadGraphResourceId, credential);
var http = new HttpClient();
var url = Globals.aadGraphEndpoint + tenant + api + "?" + Globals.aadGraphVersion;
var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await http.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
var error = await response.Content.ReadAsStringAsync();
var formatted = JsonConvert.DeserializeObject(error);
//Console.WriteLine("Error Calling the Graph API: \n" + JsonConvert.SerializeObject(formatted, Formatting.Indented));
Logger.Error("Error Calling the Graph API: \n" + JsonConvert.SerializeObject(formatted, Formatting.Indented));
}
Logger.Info((int)response.StatusCode + ": " + response.ReasonPhrase);
return await response.Content.ReadAsStringAsync();
}
Run Code Online (Sandbox Code Playgroud)
这最终解决了我的所有问题,这可能是我的 NewCustomer 类序列化中的格式错误,然后被 API 拒绝。