Deep Diver: Azure AD B2B

In this blog I focus on enterprise collaboration access scenarios, and demonstrate some peculiar insights Azure AD and AAD B2B hold in terms of issuing tokens

The Big Picture (click picture for larger version)

Click the picture for larger image

Disclaimer: The article focuses on delegated app permissions, thus you won’t see examples of App Identity & Client Credentials Flow. Neither should you assume that direct app permissions behave the same way as the scenarios demonstrated in the below paragraphs. The blog assumes previous understanding of Azure AD B2B (if you feel, that more is needed, read this excellent article describing the basics)

Tokens & Claims and resource access

Three stages of access?

Before we delve into B2B access, it’s important to understand how the resource access generally works in v1.0 endpoints with user identity driven scenarios

Click the picture for larger image

UserTypes?

UserType and Source have ”loose” correlation. Meaning you can always change the UserType. Source cannot be changed for existing account (not including the local federation), unless you delete the account, and do a specific invitation and on-boarding flow. By loose I mean, that invited user always correlates to non-native directory (but can be changed)

There is also userType OTP, which isn’t yet in the official documentation

B2B Specific general, tokens & claims articles:

MS provides only two very specific articles on these concepts when related to claims and tokens. I believe the reason is the generally excellent documentation for Azure AD Authz/authn scenarios, which is highly applicable

Under the hood?

Did you know, that you can make basically any global Azure AD tenant issue a Access Token for you’re account?… The token is worthless… Unless it held proper permissions scopes on the Client, and app specific ”acl-like” permissions for the requested application, like we demonstrated in the access stages part

What separates AAD B2B token from AAD token is that seperate IDP value is written to the B2B Token, since the final issuer is the destination directory, where the B2B user is collaborating, and not the users home directory

Lets take example from Teams

  • Flow differences
    • The local directory token is fetched against multi-tenant endpoint [common]
    • Guest token is fetched against the guest directory (issuer in our examples)

Guest token

{
    "aud": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
    "iss": "https://sts.windows.net/46d2c4e6-a732-4fb4-b9f8-374af03f3f58/",
    "iat": 1557116305,
    "nbf": 1557116305,
    "exp": 1557120205,
    "acct": 1,
    "acr": "1",
    "aio": "AUQAu/8LAAAACFsh87mJ7wZTvQe5/qq5SnS+9srK3tO5sbt5leCu0sm5Rjfx41a9x7OQpn7HbrglieuT+bsL7db6hAEIvRb/XA==",
    "altsecid": "5::100320003B090681",
    "amr": [
      "pwd"
    ],
    "appid": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
    "appidacr": "0",
    "email": "jose@ff00.info",
        "idp": "https://sts.windows.net/7fde6064-17a0-4c0e-87d6-19883001bd0d/",
    "ipaddr": "81.175.217.33",
    "name": "jose santa",
    "oid": "e648ddcb-2ea0-4a02-9a2e-ff491494846c",
    "puid": "1003200046F07AB7",
    "scp": "Contacts.ReadWrite.Shared Files.ReadWrite.All Notes.ReadWrite.All Sites.ReadWrite.All",
    "sub": "DYE_FXLPCgd1yPksPNFXov8b41jgZsedrc_W8t4bcMA",
    "tid": "46d2c4e6-a732-4fb4-b9f8-374af03f3f58",
    "unique_name": "jose@ff00.info",
    "uti": "rdex3UDBd0yBZXI5XfVEAA",
    "ver": "1.0"
  }

Local token

{
    "aud": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
    "iss": "https://sts.windows.net/7fde6064-17a0-4c0e-87d6-19883001bd0d/",
    "iat": 1557116092,
    "nbf": 1557116092,
    "exp": 1557119992,
    "acct": 0,
    "acr": "1",
    "aio": "AVQAq/8LAAAAjpEyijYGeGtKYtJ2cqQfvZpmcc5AtM+g/REMI506RwnVm6GanjOcuGmG2iv97UygfkTI/ngALSC5pEZBlmJg1xpCgujBXkajEbKmYpjlWZA=",
    "amr": [
      "pwd",
      "mfa"
    ],
    "appid": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
    "appidacr": "0",
    "family_name": "santa",
    "given_name": "jose",
    "ipaddr": "81.175.217.33",
    "name": "jose santa",
    "oid": "2995f48b-8c49-4cf9-aabc-21aef5661e15",
    "onprem_sid": "S-1-5-21-621967805-835074083-177589206-1153",
    "puid": "100320003B090681",
    "scp": "Contacts.ReadWrite.Shared Files.ReadWrite.All Notes.ReadWrite.All Sites.ReadWrite.All",
    "sub": "27ASPxuGbUTB8DlgO_kAFeoZkAUbZBkah5JhvFN5nDc",
    "tid": "7fde6064-17a0-4c0e-87d6-19883001bd0d",
    "unique_name": "jose@ff00.info",
    "upn": "jose@ff00.info",
    "uti": "AEIFj-kI00-InbpiPzlBAA",
    "ver": "1.0"
  }


Stranger questions in a Strange Land:

  • What happens when B2B users UPN changes?
    • Answer:According to my testing, the user mapping isn’t done based on UPN, but other immutable-like ID (There are bunch of those in the token claims) – Thus If the UPN changes, the mapping will still work, but it will reflect the initial UPN of the user
  • Can I do access control on group based role claims emitted from guest tenant?
    • answer: I haven’t tested this yet, but I would speculate that only the roles of the destination tenant are available, not roles from the IDP tenant (for the guest user) – Maybe there is ”exposed groups/roles” -like feature in the roadmap, that allows a scoping a select set of group-values to flow cross-tenant?
  • Which claims I shouldnt excpect to flow cross tenant in SAML federations
  • How Google and OTP authenticated users differ from other B2B sources?
    • Answer: Both require tenant context for sign-in requests, meaning common endpoints, such portal.azure.com myapps.microsoft.com eg. wont work without the destination tenant appended in the URL
https://docs.microsoft.com/en-us/azure/active-directory/b2b/one-time-passcode
https://docs.microsoft.com/en-us/azure/active-directory/b2b/google-federation
  • Can I prevent my users collaborating on another tenants?
    • Answer: You can deny external guest accounts collaborating on you’re directory, but you can’t deny you’re users collaborating on other tenants (Unless you allow very few apps, that don’t support B2B collaboration on conditional access for the users, and deny all other apps)
    • Short answer: Inbound collaboration is controllable, outbound isn’t
  • Does the MFA performed in guest tenant satisfy the MFA requirement on the guest tenant
    • Answer: No, and for good reasons. You cant simply know, in what way the guest tenant user has satisfied the MFA requirement
  • I am developing Azure AD App where I need to control groups and App Roles in Azure AD related authorizations. Which App type should I use: single, or multi-tenant?
    • Answer: With single tenant app using guest users all app roles and group permissions are on you’re control. You can also apply local conditional access policy to the application and its b2b users, which you can’t do in multi-tenant apps for B2B users
    • More: With multi-tenant app you don’t need to worry about having B2B collaboration accounts on you’re directory, but you need to build the authorization and roles directly in the app, if want retain similar control.
    • Even more: There are many scenarios where it makes sense to develop app using both app types. The multi-tenant app can act as initial staging proxy, to invoke the invitation API, enabling complete self-service on-boarding for example select group of users
  • Can we use B2B users in Azure AD Domain Services
    • Answer:
https://docs.microsoft.com/en-us/azure/active-directory-domain-services/active-directory-ds-faqs#can-guest-users-invited-to-my-directory-use-azure-ad-domain-services

Ending words

If you felt that my article didn’t cover enough, or felt vague in some areas check these excellent articles from MS.

I plan also to update the article on continuous basis, so I will try to post any updates on the article on future as well.

B2B User Types – Properties of an Azure Active Directory B2B collaboration user

B2B High Level – What is guest user access in Azure Active Directory B2B?

UserType OTP – Email one-time passcode authentication (preview)

Br, Joosua