azure-ad-b2c - 如何在 azure b2c 中识别不同类型的用户

标签 azure-ad-b2c azure-ad-graph-api

我们希望查询 azure ad b2c 目录中的用户,并以编程方式为所有类型的用户提取他们的登录电子邮件。我们理解为:

  • 标准用户
  • guest 用户 (B2B)
  • 本地用户(使用邮箱注册的B2C用户)
  • 社交用户(使用社交账号注册的 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"
            }
    

    总之,我们注意到:

    标准用户
  • userPrincipalName 看起来很正常
  • 登录电子邮件位于:userPrincipalName
  • 创建类型为:null

  • 访客用户
  • userPrincipalName 看起来是外部目录 upn,后跟“#EXT#”,然后是这个主域
  • 登录邮箱地址:otherMails[0]
  • 创建类型为:null

  • 本地用户
  • userPrincipalName 看起来是某个对象 ID,后跟此主域
  • 登录电子邮件位于:signInNames[0].value
  • 创建类型为:LocalAccount

  • 社交用户
  • userPrincipalName 看起来是“cpim_”,后跟一些对象 ID,然后是这个主域
  • 登录邮箱地址:otherMails[0]
  • 创建类型为:null

  • 尽管我们可以看到一些趋势,但我们宁愿不要做出猜测或错误的假设。所以我们有以下问题:

    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 注册个人是否安全(目前):
  • 创建类型为:null - 表示他们不是本地用户
  • userPrincipalName 以 'cpim_' 为前缀,后跟 UUID - 表示他们可能不是标准用户或访客用户

  • 或者会有更好的方法吗?

    最佳答案

    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/

    相关文章:

    java - 使用 Azure AD Graph api 更新缩略图照片的 REST 客户端示例?

    c# - 如何在没有控制台/ native 应用程序交互式登录屏幕的情况下为 Graph API 生成 Azure Active Directory (AAD) 身份验证 token ?

    使用 AD B2C 进行守护程序应用程序的 Azure 函数身份验证

    azure-ad-b2c - 在 Azure AD B2C 中,短信验证码的有效期是多长?

    azure - 在 Azure B2C 自定义登录 HTML 页面中添加脚本标记

    azure - 在 Microsoft Azure(图形)API 上过滤(搜索)

    azure - 对于 '10/15/2018' 问题之后创建的此类应用程序,不支持使用/common 端点

    azure - 使用 Azure AD B2C 的短信功能

    azure - 有没有办法使用Azure Ad Graph API来实现 'Forgot password functionality"?

    azure - Microsoft Graph Explorer 应用程序 - 权限问题