Azure AD B2C Custom User Attributes
我是Azure B2C世界的新手。我正在尝试创建"自定义用户"属性来存储我们应用程序的数据。我已经在Azure门户中创建了它,并将其分配给了我的"注册/登录"策略。但是,我希望能够以编程方式更新/读取此值。我一直在使用Graph API和注册Extensions。有两个问题:
1)扩展名/自定义属性是否相同?
2)我尝试过此代码,并且返回的扩展名始终为空:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public void RegisterExtension() { string myRegisteredAppObjectId ="<>"; string json = @"{ ""name"":""My Custom Attribute"", ""dataType"":""String"", ""targetObjects"": [ ""User"" ] }"; B2CGraphClient b2CGraphClient = new B2CGraphClient(); b2CGraphClient.RegisterExtension(myRegisteredAppObjectId, json); var extensions = JsonConvert.DeserializeObject(b2CGraphClient.GetExtensions(myRegisteredAppObjectId).Result); } |
B2CGraphClient.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | public class B2CGraphClient { private string clientId { get; set; } private string clientSecret { get; set; } private string tenant { get; set; } private AuthenticationContext authContext; private ClientCredential credential; public B2CGraphClient(string clientId, string clientSecret, string tenant) { // The client_id, client_secret, and tenant are pulled in from the App.config file this.clientId = clientId; this.clientSecret = clientSecret; this.tenant = tenant; // The AuthenticationContext is ADAL's primary class, in which you indicate the direcotry to use. this.authContext = new AuthenticationContext("https://login.microsoftonline.com/" + tenant); // The ClientCredential is where you pass in your client_id and client_secret, which are // provided to Azure AD in order to receive an access_token using the app's identity. this.credential = new ClientCredential(clientId, clientSecret); } public async Task<string> DeleteUser(string objectId) { return await SendGraphDeleteRequest("/users/" + objectId); } public async Task<string> RegisterExtension(string objectId, string body) { return await SendGraphPostRequest("/applications/" + objectId +"/extensionProperties", body); } public async Task<string> GetExtensions(string appObjectId) { return await SendGraphGetRequest("/applications/" + appObjectId +"/extensionProperties", null); } private async Task<string> SendGraphPostRequest(string api, string json) { // NOTE: This client uses ADAL v2, not ADAL v4 AuthenticationResult result = authContext.AcquireToken(Globals.aadGraphResourceId, credential); HttpClient http = new HttpClient(); string url = Globals.aadGraphEndpoint + tenant + api +"?" + Globals.aadGraphVersion; Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("POST" + url); Console.WriteLine("Authorization: Bearer" + result.AccessToken.Substring(0, 80) +"..."); Console.WriteLine("Content-Type: application/json"); Console.WriteLine(""); Console.WriteLine(json); Console.WriteLine(""); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); request.Content = new StringContent(json, Encoding.UTF8,"application/json"); HttpResponseMessage response = await http.SendAsync(request); if (!response.IsSuccessStatusCode) { string error = await response.Content.ReadAsStringAsync(); object formatted = JsonConvert.DeserializeObject(error); throw new WebException("Error Calling the Graph API: \ " + JsonConvert.SerializeObject(formatted, Formatting.Indented)); } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine((int)response.StatusCode +":" + response.ReasonPhrase); Console.WriteLine(""); return await response.Content.ReadAsStringAsync(); } public async Task<string> SendGraphGetRequest(string api, string query) { // First, use ADAL to acquire a token using the app's identity (the credential) // The first parameter is the resource we want an access_token for; in this case, the Graph API. AuthenticationResult result = authContext.AcquireToken("https://graph.windows.net", credential); // For B2C user managment, be sure to use the 1.6 Graph API version. HttpClient http = new HttpClient(); string url ="https://graph.windows.net/" + tenant + api +"?" + Globals.aadGraphVersion; if (!string.IsNullOrEmpty(query)) { url +="&" + query; } Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("GET" + url); Console.WriteLine("Authorization: Bearer" + result.AccessToken.Substring(0, 80) +"..."); Console.WriteLine(""); // Append the access token for the Graph API to the Authorization header of the request, using the Bearer scheme. HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); HttpResponseMessage response = await http.SendAsync(request); if (!response.IsSuccessStatusCode) { string error = await response.Content.ReadAsStringAsync(); object formatted = JsonConvert.DeserializeObject(error); throw new WebException("Error Calling the Graph API: \ " + JsonConvert.SerializeObject(formatted, Formatting.Indented)); } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine((int)response.StatusCode +":" + response.ReasonPhrase); Console.WriteLine(""); return await response.Content.ReadAsStringAsync(); } } |
当然,
谢谢
Are extensions/custom attributes the same thing?
根据我的测试,扩展名与自定义属性相同。
I've tried this code and the returned extensions are always empty:
我在本教程之后添加了自定义属性
我从Github下载B2C-GraphAPI-DotNet项目。将以下代码用于自定义属性
1 2 3 | var applications = client.GetApplications("$filter=startswith(displayName, 'b2c-extensions-app')").Result var extension = client.GetExtensions(objectId).Result //objectId from the applications result. |
然后我们可以从扩展名中获取自定义属性。
然后,您可以像对待用户对象上的任何其他属性一样对待该属性。
例如创建用户:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | var jsonObject = new JObject { {"accountEnabled", true}, {"country","US"}, {"creationType","LocalAccount"}, {"displayName","Tomsun"}, {"passwordPolicies","DisablePasswordExpiration,DisableStrongPassword"}, {"extension_42ba0de8530a4b5bbe6dad21fe6ef092_MyCustomAttribute","test2"}, //custom propery {"passwordProfile", new JObject { {"password","!QAZ1234wer"}, {"forceChangePasswordNextLogin", true} } }, {"signInNames", new JArray { new JObject { {"value","[email protected]"}, {"type","emailAddress"} } } } }; string user = client.CreateUser(jsonObject.ToString()).Result; |
查询用户
1 | var user = client.GetUserByObjectId(objectId).Result; //user objectId |
更新用户
1 2 3 4 5 6 | var jsonUpdate = new JObject { {"extension_42ba0de8530a4b5bbe6dad21fe6ef092_MyCustomAttribute","testx"} }; var updateuser = client.UpdateUser("objectId", jsonObject2.ToString()).Result; //UserObject Id |