Brief testing: Converting internal on-premises accounts to B2B collaboration accounts

One of the recent features that had slipped from my radar, is the capability to make internal accounts authenticate with their credentials in another Azure AD tenant. All this is done while still retaining groups and assignments of the original account in the resource tenant. This feature could be described as *merge of accounts, while not technically exactly correct, its descriptive of the change nonetheless

* user retains access for sign-in for both accounts. It is more technically correct to say, that the same object is mapped to different sources, as we can see after the user is invited for b2b collaboration by looking at the user object


In this blog I wanted take the feature for quick test drive, so if you are looking for more comprehensive post, then I recommend to read the docs article

  • This feature works also for non-synchronized Azure AD accounts, but I highlight this particular scenario, as its most common scenario for me (external users having internal ad account with ”ext-” prefix)
  • Recommended reading is to understand the limitations regarding accounts in the article, and how the authentication works after the change
  • Even after the change, the account will be shown as member, I am guessing, that this doesn’t affect the B2B licensing, but would be interesting to understand, how licensing works from here. The important take is, that the user type is member, not guest. Meaning the user retains the same rights, that the object had originally (Typically when user is guest, they have limited rights in the directory)


The main benefit is that even after partner changes authentication to tenant2, partner can still continue on-premises access, and collaboration in the cloud while retaining group and app assignments in tenant 1.

The difference is, that after the merge, partner will use account in tenant 2 to authenticate to tenant 1 – from there account will continue tenant 1’s user context

Testing the switch

To begin I had synchronized test account in tenant 1. and the corresponding account (the account I want to invite for B2B collaboration) in tenant 2.

user Tenant 1 ext-roger.telark@dewi.red (this is the original user account)

user in Tenant2 roger.telark@azdv.work (this the user that accepts the invite)

  • Invite user to B2B collaboration, by including objectID of tenant1 user, and mail attribute, which should match in both tenants (this is important, as otherwise the invite will fail)
  • After running the script (below) and user accepting the invite can see that the source attribute has changed to type ’multiple’
  • After the change if original user of tenant 1 is added to new Teams channel, the account in tenant 2 will get the notification, and can sign-in to the account using credentials in tenant 2.
  • Here is examples from ”Internal testing file-sharing app”
    • Note the changes in the user attributes, after user starts authenticating with account in tenant 2
Original user
b2b collaboration user – Note that the idp claim is added, and unique name is different (based on tenant2)

In teams user will retain the display name (and everything else) from the tenant1 object

Invite script example (NodeJS)

const rq = require('request')
const fs = require('fs')

var getClientCredentialsToken = ({
}, callback) => {

    var options = {
        json: true,
        headers: [{
            "content-type": "application/x-www-form-urlencoded"
        form: {
            grant_type: "client_credentials",

    rq.post("https://login.microsoftonline.com/dewired.onmicrosoft.com/oauth2/token", options, (error, response) => {
        fs.writeFileSync('ctoken.JSON', JSON.stringify(response.body))
        callback(response.body, options)


var ob = {
    client_id: "",
    resource: "https://graph.microsoft.com",
    client_secret: ""

getClientCredentialsToken(ob, (response, options) => {

    console.log(response, options)

    options.method = "POST"
    var uri = options.form.resource + '/v1.0/invitations'
    delete options.form
    options.headers.authorization = 'Bearer ' + response['access_token']
    options.headers['content-type'] ="application/json"
    options.body = {
        "invitedUserEmailAddress": "roger.telark@azdv.work",
        "sendInvitationMessage": true,
        "invitedUserMessageInfo": {
            "messageLanguage": "en-US",
            "customizedMessageBody": "nost",
        "inviteRedirectUrl": "https://myapps.microsoft.com",
        "invitedUser": {
            "id": "430e304a-a3a9-48ca-a6ba-f4c4c5b8ef63"
    rq(uri,options, (error,response) => {


Thx for reading this far!

Further tests, and some security aspects shall be covered in follow-up post

Credits for the inspiration of the post



1 comment on “Brief testing: Converting internal on-premises accounts to B2B collaboration accounts

  1. Paluuviite: Experimental testing: Updating source authority for existing B2B collaboration user to type ’Multiple’ by matching syncing AD object – SecureCloudBlog


Täytä tietosi alle tai klikkaa kuvaketta kirjautuaksesi sisään:


Olet kommentoimassa WordPress.com -tilin nimissä. Log Out /  Muuta )


Olet kommentoimassa Facebook -tilin nimissä. Log Out /  Muuta )

Muodostetaan yhteyttä palveluun %s

%d bloggaajaa tykkää tästä: