我们希望查询 azure ad b2c 目录中的用户,并以编程方式为所有类型的用户提取他们的登录电子邮件。我们理解为:
使用 azure ad graph explorer 运行 api 调用时:
https://graph.windows.net/myorganization/users?api-version=1.6
我们可以看到所有这些用户。 (数据被清理了一点)
示例标准用户
{
"odata.type": "Microsoft.DirectoryServices.User",
"objectType": "User",
"objectId": "8b7c468b-fec4-4ff2-b448-64f99f3fa9ff",
"deletionTimestamp": null,
"accountEnabled": true,
"assignedLicenses": [],
"assignedPlans": [],
"city": null,
"companyName": null,
"country": null,
"creationType": null,
"department": null,
"dirSyncEnabled": null,
"displayName": "Global User",
"employeeId": null,
"facsimileTelephoneNumber": null,
"givenName": null,
"immutableId": null,
"isCompromised": null,
"jobTitle": null,
"lastDirSyncTime": null,
"mail": null,
"mailNickname": "global.user",
"mobile": null,
"onPremisesDistinguishedName": null,
"onPremisesSecurityIdentifier": null,
"otherMails": [],
"passwordPolicies": null,
"passwordProfile": null,
"physicalDeliveryOfficeName": null,
"postalCode": null,
"preferredLanguage": null,
"provisionedPlans": [],
"provisioningErrors": [],
"proxyAddresses": [],
"refreshTokensValidFromDateTime": "2017-10-31T17:20:29Z",
"showInAddressList": null,
"signInNames": [],
"sipProxyAddress": null,
"state": null,
"streetAddress": null,
"surname": null,
"telephoneNumber": null,
"usageLocation": null,
"userIdentities": [],
"userPrincipalName": "global.user@qa2clientb2ctheaccesshub.onmicrosoft.com",
"userType": "Member"
}
guest 用户示例
{
"odata.type": "Microsoft.DirectoryServices.User",
"objectType": "User",
"objectId": "6458e1fc-c27b-40cb-b83d-2124f0999130",
"deletionTimestamp": null,
"accountEnabled": true,
"assignedLicenses": [],
"assignedPlans": [],
"city": null,
"companyName": null,
"country": null,
"creationType": null,
"department": null,
"dirSyncEnabled": null,
"displayName": "displayname",
"employeeId": null,
"facsimileTelephoneNumber": null,
"givenName": "givenname",
"immutableId": null,
"isCompromised": null,
"jobTitle": null,
"lastDirSyncTime": null,
"mail": null,
"mailNickname": "qa_theaccesshub.com#EXT#",
"mobile": null,
"onPremisesDistinguishedName": null,
"onPremisesSecurityIdentifier": null,
"otherMails": [
"qa@theaccesshub.com"
],
"passwordPolicies": null,
"passwordProfile": null,
"physicalDeliveryOfficeName": null,
"postalCode": null,
"preferredLanguage": null,
"provisionedPlans": [],
"provisioningErrors": [],
"proxyAddresses": [],
"refreshTokensValidFromDateTime": "2017-10-31T15:36:22Z",
"showInAddressList": null,
"signInNames": [],
"sipProxyAddress": null,
"state": null,
"streetAddress": null,
"surname": "surname",
"telephoneNumber": null,
"usageLocation": null,
"userIdentities": [],
"userPrincipalName": "qa_theaccesshub.com#EXT#@qa2clientb2ctheaccesshub.onmicrosoft.com",
"userType": "Member"
}
本地用户示例
{
"odata.type": "Microsoft.DirectoryServices.User",
"objectType": "User",
"objectId": "a941e75d-2c1b-4383-9d6c-783c1d008479",
"deletionTimestamp": null,
"accountEnabled": true,
"assignedLicenses": [],
"assignedPlans": [],
"city": null,
"companyName": null,
"country": null,
"creationType": "LocalAccount",
"department": null,
"dirSyncEnabled": null,
"displayName": "Display Name",
"employeeId": null,
"facsimileTelephoneNumber": null,
"givenName": "Glen",
"immutableId": null,
"isCompromised": null,
"jobTitle": null,
"lastDirSyncTime": null,
"mail": null,
"mailNickname": "98c4f2cf-a452-46a4-a33f-6fb451bc3f59",
"mobile": null,
"onPremisesDistinguishedName": null,
"onPremisesSecurityIdentifier": null,
"otherMails": [],
"passwordPolicies": "DisablePasswordExpiration",
"passwordProfile": null,
"physicalDeliveryOfficeName": null,
"postalCode": null,
"preferredLanguage": null,
"provisionedPlans": [],
"provisioningErrors": [],
"proxyAddresses": [],
"refreshTokensValidFromDateTime": "2017-11-03T18:18:36Z",
"showInAddressList": null,
"signInNames": [
{
"type": "emailAddress",
"value": "login.email@example.com"
}
],
"sipProxyAddress": null,
"state": null,
"streetAddress": null,
"surname": "Martin",
"telephoneNumber": null,
"usageLocation": null,
"userIdentities": [],
"userPrincipalName": "98c4f2cf-a452-46a4-a33f-6fb451bc3f59@qa2clientb2ctheaccesshub.onmicrosoft.com",
"userType": "Member"
}
示例社交用户
{
"odata.type": "Microsoft.DirectoryServices.User",
"objectType": "User",
"objectId": "917bddd5-40d8-4a25-9a6e-8317a6949b48",
"deletionTimestamp": null,
"accountEnabled": false,
"assignedLicenses": [],
"assignedPlans": [],
"city": null,
"companyName": null,
"country": null,
"creationType": null,
"department": null,
"dirSyncEnabled": null,
"displayName": "Display Name",
"employeeId": null,
"facsimileTelephoneNumber": null,
"givenName": "GivenName",
"immutableId": null,
"isCompromised": null,
"jobTitle": null,
"lastDirSyncTime": null,
"mail": null,
"mailNickname": "unknown",
"mobile": null,
"onPremisesDistinguishedName": null,
"onPremisesSecurityIdentifier": null,
"otherMails": [
"another.login.email@example.com"
],
"passwordPolicies": null,
"passwordProfile": {
"password": null,
"forceChangePasswordNextLogin": true,
"enforceChangePasswordPolicy": false
},
"physicalDeliveryOfficeName": null,
"postalCode": null,
"preferredLanguage": null,
"provisionedPlans": [],
"provisioningErrors": [],
"proxyAddresses": [],
"refreshTokensValidFromDateTime": "2017-11-02T13:48:09Z",
"showInAddressList": null,
"signInNames": [],
"sipProxyAddress": null,
"state": null,
"streetAddress": null,
"surname": "Surname",
"telephoneNumber": null,
"usageLocation": null,
"userIdentities": [],
"userPrincipalName": "cpim_662effe2-cd73-4f4a-8b42-2af5f68b2db1@qa2clientb2ctheaccesshub.onmicrosoft.com",
"userType": "Member"
}
总之,我们注意到:
标准用户
访客用户
本地用户
社交用户
尽管我们可以看到一些趋势,但我们宁愿不要做出猜测或错误的假设。所以我们有以下问题:
1) 了解我们正在查看的四种用户中哪一种的最佳方法是什么?
2) 有没有一种更简单的方法来获取登录名(理想情况下,作为一个字段,我们正在尝试将其构建为一个简单的映射)?以外 :
If signInNames[0].value is not null use signInNames[0].value
Elseif otherMails[0] is not null use otherMails[0]
Else userPrincipalName
3) 其他社交用户的行为是否不同? (到目前为止,我们只做过 Facebook。)
4) 对于社交用户,了解使用哪个身份提供者的最佳方式是什么?
11/8 更新:
5) 为什么LocalAccount 用户没有得到otherMail 值?
6) 为什么非 LocalAccount 用户没有登录名?我猜那是专门为 B2C 添加的?
7) 另外我猜终端用户今天真的没有能力关联社交和本地帐户? (除非使用利用图表的应用程序)。
更新 11/8 #2:
8) 假设我可以使用以下标准消除只能使用社交帐户登录的 B2C 注册个人是否安全(目前):
或者会有更好的方法吗?
最佳答案
1) 这些不是相互排斥的属性。例如,本地帐户、访客或成员用户也可以将他们的多个社交资料链接到他们的帐户。底层数据(可通过 Graph API 获得)不做任何假设。
了解帐户是否为本地用户的最可靠方法是查看 creationType 属性。您还可以查看signInNames。话虽如此,但这并不意味着用户将来不会链接他们的社交资料。只是此功能未在 B2C 标准策略中公开。
2) signInNames
当然用于登录用户。但是,一个用户也可以拥有多个 signInName
就目录而言。这就是为什么signInNames
是一个集合。因此,公用事业公司或银行的帐户 ID 和电子邮件地址可能都为 signInNames
。 .otherMails
不是用于登录用户的属性。所以你可能想跳过它。想想otherMails
作为目录不用于任何关键功能的电子邮件地址(例如,它不用于登录或密码重置等)
您将使用 userPrincipalName
用于工作帐户。
3)所有社交账户都被视为外部用户身份,并以相同的方式映射。它们还不能通过 Graph API 使用,但是当它们可用时,它们也会显示为一个集合,因为用户可能会链接到多个社交帐户。
4)今天不可能,但将来会出现。
更新 11/8 回答其他问题
5) 仅仅因为B2C标准流程中没有邮箱地址可以添加otherMails
对于本地帐户用户。他们用来注册的邮箱地址已经在signInNames
属性(property)。通过 Graph API,您可以添加 otherMails
,并且当一个 token 被发行时,它将显示在 emails
甚至为本地帐户用户声明。
6) 非本地账号用户收不到signInName
因为他们不需要使用 signInNames
登录.工作帐户使用 userPrincipalName
相反,它可以绑定(bind)到 Office 365、Exchange 或本地 AD。社会国内流离失所者具有外部身份。因此,不存在signInNames
的已知场景。至少今天需要用于非本地帐户。
7) 是的,现在无法通过标准策略将社交帐户与本地帐户关联,但可以通过自定义策略来完成。通过 Graph API 也无法实现(因为尚未公开外部身份),但在 future 公开 API 时将成为可能。
11/24 更新:
8) 如果您查看用户主体名称,您会发现它是随机的。 cpim_ 可以随时删除,它不是契约(Contract)的一部分。事实上,恕我直言,它应该已经被删除,所以应用程序不会依赖它。
为了正确确定这一点,我们预计会在用户帐户上发布一个新的“userIdentities”属性,您可以使用它来确定用户帐户链接到哪些社交 IDP。那将是做到这一点的最好方法。
关于azure-ad-b2c - 如何在 azure b2c 中识别不同类型的用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47143711/