英文:
Bulk upload user using JSON file to Azure B2C active directory in Java
问题
我连接了我的Java代码到Azure B2C活动目录,并使用了以下代码:
User user = graphClient.users("611us0f2a-7608-4edd-8c4c-7871d8e70b8e").buildRequest().get();
在get()
请求中得到了结果,这意味着我的连接是正确的,现在我想批量上传已存在于本地数据库中的用户,我创建了一个JSON格式的文件(user_data.json),它看起来像这样:
{
"users": [
{
"displayName": "Amanda Polly",
"givenName": "Amanda",
"surname": "Polly",
"extension_user_type": "user",
"identities": [
{
"signInType": "emailAddress",
"issuerAssignedId": "amandapolly@gmail.com"
}
],
"extension_timezone": "PST",
"extension_locale": "en-US",
"extension_tenant": "EG1234"
},
{
"displayName": "Lowa Doe",
"givenName": "Lowa",
"surname": "Doe",
"extension_user_type": "user",
"identities": [
{
"signInType": "userName",
"issuerAssignedId": "lowadow123"
}
],
"extension_timezone": "PST",
"extension_locale": "en-US",
"extension_tenant": "EG1234"
}
]
}
在JSON中,我有一个包装器"users",然后是所有用户(在JSON中有2个用户),现在我必须使用Microsoft Graph API 创建它们,我该如何操作?
我知道我需要将每个用户转换为对象,然后使用post()
发送它们以在目录中创建它们。请为如何操作提供解决方案。
在你的代码中:
private static void updateExtension(String userID, IGraphServiceClient graphClient) {
User extensionForUser = new User();
extensionForUser.additionalDataManager().put("extension_dfa4f1a9a2f94cd1bf8826c50d4d0464_user_type", new JsonPrimitive(extension_user_type));
// ...
graphClient.users(userID)
.buildRequest()
.patch(extensionForUser);
}
它在.patch(extensionForUser)
处中断,并显示错误:
Error message: Resource 'null' does not exist or one of its queried reference-property objects are not present.
PATCH https://graph.microsoft.com/v1.0/users/null
SdkVersion : graph-java/v1.9.0
Authorization : Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI[...]
{"extension_dfa4f1a9a2f94cd1bf8826c50d4d0464_tenan[...]
404 : Not Found
[...]
但当我检查Azure目录时,用户已创建。因为当我重新运行代码时,它说一个具有相同主体名称的用户已存在。
此外,由于它在第一次迭代中中断,后面的用户没有被创建。
根据你提供的更新,我看到你有一个用于创建用户的循环。在每次迭代中,你使用了userCreateCall()
方法创建用户,然后尝试使用这些用户数据来调用updateExtension()
方法,但在updateExtension()
中,userID
参数似乎是 null
。
关于这个问题,根本原因可能是userCreateCall()
方法返回了 null
,导致userID
也为 null
,进而导致updateExtension()
失败。你需要确保userCreateCall()
方法正确地返回了创建用户后的ID。
在你提供的代码片段中,userCreateCall()
方法似乎是这样定义的:
User buildUserRequest = graphClient.users()
.buildRequest()
.post(createNewUser);
return createNewUser.id;
请确保createNewUser.id
不是 null
,并且在userCreateCall()
方法中没有出现问题,这样userID
才能正确地传递给updateExtension()
方法。检查createNewUser.id
是否被正确设置和返回。
此外,请确保在userCreateCall()
方法内部,用户被成功创建,并且createNewUser.id
在这个方法内被正确设置。如果这个方法在创建用户时出现了问题,createNewUser.id
可能会保持为 null
,导致后续的问题。
根据你提供的信息,这是一个可能的解释和解决方法。如果问题仍然存在,请进一步检查 userCreateCall()
方法的实现,确保它正确地创建用户并返回相应的用户ID。
英文:
I connected my java code to the Azure B2C active directory and used
User user = graphClient.users("611us0f2a-7608-4edd-8c4c-7871d8e70b8e").buildRequest().get();
I got result in get() request which mean my connection is correct, now I wan to bulk upload users that are existing in my local db, I created a JSON format file which (user_data.json), it looks like this -
{
"users": [
{
"displayName": "Amanda Polly",
"givenName": "Amanda",
"surname": "Polly",
"extension_user_type": "user",
"identities": [
{
"signInType": "emailAddress",
"issuerAssignedId": "amandapolly@gmail.com"
}
],
"extension_timezone": "PST",
"extension_locale": "en-US",
"extension_tenant": "EG1234"
},
{
"displayName": "Lowa Doe",
"givenName": "Lowa",
"surname": "Doe",
"extension_user_type": "user",
"identities": [
{
"signInType": "userName",
"issuerAssignedId": "lowadow123"
}
],
"extension_timezone": "PST",
"extension_locale": "en-US",
"extension_tenant": "EG1234"
}
]
}
Here in the JSON, I have a wrapper "users" and then followed by all the users (2 users as of now if you see in JSON), so now I have to create them using mircosoft graph api, how do I proceed? what i know, i have to covert each of the user into an object and the use post() to send to create them in the directory.
Please suggest a solution for how to do it.
||For you to read Allen, as you suggested, when the code is coming to,
private static void updateExtension(String userID, IGraphServiceClient graphClient)
{
User extensionForUser = new User();
extensionForUser.additionalDataManager().put("extension_dfa4f1a9a2f94cd1bf8826c50d4d0464_user_type", new JsonPrimitive(extension_user_type));
extensionForUser.additionalDataManager().put("extension_dfa4f1a9a2f94cd1bf8826c50d4d0464_timezone", new JsonPrimitive(extension_timezone));
extensionForUser.additionalDataManager().put("extension_dfa4f1a9a2f94cd1bf8826c50d4d0464_extension_locale", new JsonPrimitive(extension_locale));
extensionForUser.additionalDataManager().put("extension_dfa4f1a9a2f94cd1bf8826c50d4d0464_tenant", new JsonPrimitive(extension_tenant));
graphClient.users(userID)
.buildRequest()
.patch(extensionForUser);
}
It is breaking at .patch(extensionForUser) --> with error like
Error message: Resource 'null' does not exist or one of its queried reference-property objects are not present.
PATCH https://graph.microsoft.com/v1.0/users/null
SdkVersion : graph-java/v1.9.0
Authorization : Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI[...]
{"extension_dfa4f1a9a2f94cd1bf8826c50d4d0464_tenan[...]
404 : Not Found
[...]
But when I checked my Azure Directory, the user was created. Because when i re ran the code, it said a user already exist with same principal name.
Also since it is breaking in the first iteration, users to be created behind this are not getting created.
Update 3 : Explanation to what I tried.
userID = userCreateCall(displayName, givenName, surname, extension_user_type, extension_timezone, extension_locale, extension_tenant, signInType, issuerAssignedId, graphClient);
System.out.println(userID);
updateExtension(userID, graphClient, extension_user_type, extension_timezone, extension_locale, extension_tenant);
If you see I have a for loop that will iterate through every user and in every iteration, it will pick [displayName, givenName, surname, extension_user_type, extension_timezone, extension_locale, extension_tenant, signInType, issuerAssignedId] for each user and pass it as a parameter to userCreateCall() method as you can see in above code, I am also passing graphClient within the param.
This is my userCreateCall() method,
User createNewUser = new User();
createNewUser.displayName = displayName;
createNewUser.givenName = givenName;
createNewUser.surname = surname;
LinkedList<ObjectIdentity> identitiesList = new LinkedList<ObjectIdentity>();
ObjectIdentity identities = new ObjectIdentity();
identities.signInType = signInType;
identities.issuerAssignedId = issuerAssignedId;
identities.issuer = "demoUserEngine.onmicrosoft.com";
identitiesList.add(identities);
createNewUser.identities = identitiesList;
PasswordProfile passwordProfile = new PasswordProfile();
passwordProfile.password = "passwordPASSWORD!";
passwordProfile.forceChangePasswordNextSignIn = false;
createNewUser.passwordProfile = passwordProfile;
createNewUser.passwordPolicies = "DisablePasswordExpiration";
User buildUserRequest = graphClient.users()
.buildRequest()
.post(createNewUser);
return createNewUser.id;
I am returning createNewUser.id but I think it is coming NULL here, hence
userID = userCreateCall(displayName, givenName, surname, extension_user_type, extension_timezone, extension_locale, extension_tenant, signInType, issuerAssignedId, graphClient);
System.out.println(userID); // THIS IS giving NULL
So when calling update updateExtension
userID is going as NULL,
I commented the updateExtension method so that I wont have to use userID and code did not break, no exception in user creation, just the userID is coming NULL.
答案1
得分: 1
以下是翻译好的部分:
不能直接使用扩展属性在Azure B2C中创建用户。
我们应该首先使用常规属性创建用户,然后再更新用户的扩展属性。
首先,您需要通过按照创建自定义属性中的步骤,在Azure门户中创建扩展属性(extension_user_type
、extension_timezone
、extension_locale
、extension_tenant
)。请注意,您只需将user_type
、timezone
、locale
、tenant
输入为扩展属性的名称。
然后,它会生成扩展属性,格式为:extension_ApplicationClientID_attributename
,其中ApplicationClientID是b2c-extensions-app
应用程序的应用程序(客户端)ID(在Azure门户的应用注册 > 所有应用程序中找到)。
请注意,扩展属性名称中表示的应用程序(客户端)ID不包括连字符。例如,b2c-extensions-app
应用程序的应用程序ID是a554ad42-83c8-475e-a9aa-ac09a9h25c67
。但实际的扩展属性是extension_a554ad4283c8475ea9aaac09a9h25c67_attributename
,其中移除了所有的-
。参考此处。
现在,我们准备创建用户。请参考我的代码:
public static void main(String[] args) {
List<String> scopes = Arrays.asList("https://graph.microsoft.com/.default");
String clientId = "3******9-5a11-4823-88de-13*******cad";
String clientSecret = "**********************************";
String tenant = "allentest001.onmicrosoft.com";
ClientCredentialProvider authProvider = new ClientCredentialProvider(
clientId,
scopes,
clientSecret,
tenant,
NationalCloud.Global);
IGraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
String userId = createUser(graphClient);
updateExtension(userId, graphClient);
}
private static String createUser(IGraphServiceClient graphClient) {
User user = new User();
user.displayName = "Amanda Polly";
user.givenName = "Amanda";
user.surname = "Polly";
LinkedList<ObjectIdentity> identitiesList = new LinkedList<ObjectIdentity>();
ObjectIdentity identities = new ObjectIdentity();
identities.signInType = "emailAddress";
identities.issuer = "allentest001.onmicrosoft.com";
identities.issuerAssignedId = "amandapolly@gmail.com";
identitiesList.add(identities);
user.identities = identitiesList;
PasswordProfile passwordProfile = new PasswordProfile();
passwordProfile.password = "{your password here}";
passwordProfile.forceChangePasswordNextSignIn = false;
user.passwordProfile = passwordProfile;
user.passwordPolicies = "DisablePasswordExpiration";
User newUser = graphClient.users()
.buildRequest()
.post(user);
return newUser.id;
}
private static void updateExtension(String userId, IGraphServiceClient graphClient) {
User user = new User();
user.additionalDataManager().put("extension_a554ad4283c8475ea9aaac09a9h25c67_user_type", new JsonPrimitive("user"));
user.additionalDataManager().put("extension_a554ad4283c8475ea9aaac09a9h25c67_timezone", new JsonPrimitive("PST"));
user.additionalDataManager().put("extension_a554ad4283c8475ea9aaac09a9h25c67_extension_locale", new JsonPrimitive("PST"));
user.additionalDataManager().put("extension_a554ad4283c8475ea9aaac09a9h25c67_tenant", new JsonPrimitive("EG1234"));
graphClient.users(userId)
.buildRequest()
.patch(user);
}
请注意,在创建用户时需要设置密码。(详细信息请参见我的代码)
英文:
You can't create the user in Azure B2C with your extension attributes directly.
We should create the user with the normal attributes first and then update the extension attributes for the user.
First of all you need to create the extension attributes (extension_user_type
, extension_timezone
, extension_locale
, extension_tenant
) in Azure Portal by following Create a custom attribute. Please note you just enter user_type
, timezone
, locale
, tenant
as the name of the extension attribute.
Then it will generate the extension attribute with the format: extension_ApplicationClientID_attributename
, where the ApplicationClientID is the Application (client) ID of the b2c-extensions-app
application (found in App registrations > All Applications in the Azure portal).
Note that the Application (client) ID as it's represented in the extension attribute name includes no hyphens. For example, my application id of b2c-extensions-app
application is a554ad42-83c8-475e-a9aa-ac09a9h25c67
. But the actual extension attribute is extension_a554ad4283c8475ea9aaac09a9h25c67_attributename
, which has removed all the -
. See reference here.
Now we are preparing to create the user. Please refer to my code:
public static void main(String[] args) {
List<String> scopes = Arrays.asList("https://graph.microsoft.com/.default");
String clientId = "3******9-5a11-4823-88de-13*******cad";
String clientSecret = "**********************************";
String tenant = "allentest001.onmicrosoft.com";
ClientCredentialProvider authProvider = new ClientCredentialProvider(
clientId,
scopes,
clientSecret,
tenant,
NationalCloud.Global);
IGraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();
String userId = createUser(graphClient);
updateExtension(userId, graphClient);
}
private static String createUser(IGraphServiceClient graphClient) {
User user = new User();
user.displayName = "Amanda Polly";
user.givenName = "Amanda";
user.surname = "Polly";
LinkedList<ObjectIdentity> identitiesList = new LinkedList<ObjectIdentity>();
ObjectIdentity identities = new ObjectIdentity();
identities.signInType = "emailAddress";
identities.issuer = "allentest001.onmicrosoft.com";
identities.issuerAssignedId = "amandapolly@gmail.com";
identitiesList.add(identities);
user.identities = identitiesList;
PasswordProfile passwordProfile = new PasswordProfile();
passwordProfile.password = "{your password here}";
passwordProfile.forceChangePasswordNextSignIn = false;
user.passwordProfile = passwordProfile;
user.passwordPolicies = "DisablePasswordExpiration";
User newUser = graphClient.users()
.buildRequest()
.post(user);
return newUser.id;
}
private static void updateExtension(String userId, IGraphServiceClient graphClient) {
User user = new User();
user.additionalDataManager().put("extension_a554ad4283c8475ea9aaac09a9h25c67_user_type", new JsonPrimitive("user"));
user.additionalDataManager().put("extension_a554ad4283c8475ea9aaac09a9h25c67_timezone", new JsonPrimitive("PST"));
user.additionalDataManager().put("extension_a554ad4283c8475ea9aaac09a9h25c67_extension_locale", new JsonPrimitive("PST"));
user.additionalDataManager().put("extension_a554ad4283c8475ea9aaac09a9h25c67_tenant", new JsonPrimitive("EG1234"));
graphClient.users(userId)
.buildRequest()
.patch(user);
}
Please note you should set a password while creating the user. (see details in my code)
答案2
得分: 0
创建单个用户时,您需要在Java中为每个用户进行调用。有关此内容,请参阅此处的API文档。但是,Graph SDK还支持批处理。您可以组合包含单个请求的JSON有效负载,并将其作为单个POST请求发送到$batch端点。有关详细信息,请参阅此处。
注意:有关Microsoft Graph中JSON批处理的当前限制,请参阅已知问题。
英文:
To create single user at a time, you need to make call for each of your user in Java. Please refer the API doc for that here. But Graph SDK also supports batching. You can compose your JSON payload consisting of individual requests and make a single POST to $batch endpoint. Please refer this for details.
NOTE: For current limitations with JSON batching in Microsoft Graph, see Known Issues.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论