Tag Archives: Azure AD B2B

Explore Microsoft Graph as a B2B Guest Account

The Microsoft Graph Explorer (https://aka.ms/ge) is always a great learning source and useful tool for querying the Microsoft Graph, especially as you can use your own Azure AD work account or Microsoft account to query for real data. Another advantage with the Graph Explorer is that you can use it without requiring an App Registration in your tenant, something most users are not able to do themselves as they don’t have the administrator rights for registering apps.

However, sometimes working with Microsoft Graph, I find myself in a scenario where I want to use my own work account, but where the Microsoft Graph resources I want to query is in another Organization’s tenant. These kind of scenarios is usually where my account is invited as a B2B guest user to the resource tenant, and currently there are no way to use the Graph Explorer tool to do that.

So I need another tool, and as an IT pro I could easily write myself some PowerShell code, or as a developer I could create a Web app or Console app querying Graph, and run the queries against the other tenant from there.

On the other hand, I want to do this more inline with the Graph Explorer experience, so the most logical choice for me is to use a tool where I can just run the REST API queries I like. And the most popular tool, both by me and many others are the “Postman” client. You can get it yourself for free at https://www.getpostman.com, both Windows, Linux and Mac downloads are supported!

So in this blog post I will show how I use Postman to query Microsoft Graph in a B2B Guest User scenario.

Requirements & Preparation

So, first you will need to get invited to another tenant where the resources you wan’t to query is. You might already have this Azure AD B2B invitation accepted previously. If you aren’t an administrator in that tenant, you will have to ask someone that has the rights to invite to do that for you.

Next, you will need to get assigned permissions to the resources you want to query in the resource tenant. This is all dependent on what kind of queries you want to run, whether it is for reading, writing or deleting resources for example.

Then, you will need an Global Administrator in that resource tenant to create an App Registration. The following instructions and screenshots can be used as a guide:

First, under the Azure AD experience in the Azure Portal, go to App Registrations and create a new Registration, type a name and a redirect URI like shown below:

image

You can type any name you like, for example in this scenario I want to use it for querying identities. I choose to support accounts in this organizational directory only, as this app registration is for members or guests from this tenant. And since I will be using the Postman i specify the redirect URI of “https://www.getpostman.com/oauth2/callback”. This is important as when I authenticate from Postman later the response will be returned to the Postman client.

When accessing Microsoft Graph you have to authenticate using one of the Oauth2 flows, and the most common is using authorization code flow, (https://developer.microsoft.com/en-us/graph/blogs/30daysmsgraph-day-12-authentication-and-authorization-scenarios/), which is exactly this scenario is all about as I will authenticate on behalf of my guest user account in the resource tenant. That means that I will have to add some delegated Graph permissions to the app registration, and in this example I add User.ReadBasic.All, this will make me able to query users via Graph:

image

After granting Admin consent for the permissions, I can verify that the permissions are added correctly:

image

Next I will need to create a client secret to be used in the request to get an access token, go to certificates & secrets and add a client secret of chosen time expiry:

image

Copy and make sure you save the client secret for later next:

image

Then copy the application id and tenant id and save for later:

image

Click on endpoints (see arrow above), and note the Oauth2 authorization and token endpoints (v2), this endpoints contains the tenantid:

image

With these steps the requirements are complete and we can move on to the postman client.

Authenticating and Querying Graph with Postman

There are a lot of features in the Postman client that you should look into when working with REST API’s. You can organize your queries in Collections, save variables in Environments, synchronize your requests across devices and so on. But for now we will start simple and easy.

In the main canvas at your workspace, create a new query, and for example start with https://graph.microsoft.com/v1.0/me:

image

Don’t push Send just yet, we need to authenticate first. Go to the Authorization section under the request, and select Oauth2, then click Get New Access Token:

image

In the following dialog fill in your details as shown below, where:

  • Token Name: You can type what you want here, this is named reference to the Access Token you will aquire.
  • Grant Type: As earlier mentioned, running graph queries as the logged in user (delegated) use the Authorization Code Oauth2 flow.
  • Callback URL: This is the URL that you specified earlier for Redirect URI under the Azure AD App Registration.
  • Auth URL and Access Token URL: These are the URL’s you saw earlier from the Endpoints setting for the Azure AD App Registration (contains the Tenant ID).
  • Client ID: This is the Application ID for the App Registration.
  • Client Secret: This is the secret key you generated under the App Registration.
  • Scope: Provide a default scope, use the default.
  • State: Scope is used for creating application logic that prevents cross use of Access Tokens. You can type anything you want here.
  • Client Authentication: Select to Send client credentials in body when working with Graph requests.
image

When you click request token, you will be taken to the resource tenant for authenticating with your delegated user. Type in your username and click next. This username can either be a normal user that belongs to this resource tenant, or in this case you can log in with your B2B Guest Account:

image

Now dependent on any Conditional Access policies and settings you might be required to approve sign in:

image

After successfully authenticating I should receive a valid Access Token:

image

If you get an error here, please verify your App Registration settings and that the account you logged in as is correct.

Scroll down and click Use Token:

image

You will see that the Access Token is now filled in the Access Token textbox. Next click Preview Request down to the left, this will add the Access Token to the request as a authorization header:

image

If you click on Headers, you can see the Authorization header has been added with the access token as a Bearer Token value:

image

This Access Token is now valid for 1 hour, and you can run as many requests you like as long as you are inside the delegated permissions (for the App Registration) and the logged in users actual permissions. After 1 hour you can request a new Access Token.

PS! Postman will save the authenticated user session in cookies, if you want to log in as a different user clear those cookies, se “cookies” link right below the Send button.

So, now lets run this query, click Send at verify the response, you should get details for your guest user. From the screenshot below you can clearly see that this user is a Guest account looking at the userPrincipalName attribute:

image

Lets try another query, in this query I list all users that has userPrincipalName that starts with “Jan”, and showing only the displayName and userPrincipalName attributes:

image

As you can see from the result above, I have several guest accounts in this tenant (Microsoft Account, Google, Azure AD) as well as a normal user account. You can also see that the Postman client is helpful in specifying my parameters.

Inspecting a B2B Guest Access Token

If you copy the Access Token you got earlier, and paste it into a site like jwt.ms or jwt.io, we can take a look at the access token contents and claims:

image

If I scroll down a little I see the displayname of the App Registration, but the most important info is the mail claim, which for Guest users will be the external e-mail address. Idp is the source authority for the Guest account, in this case another Azure AD tenant with the Tenant Id as shown below:

image

Working with Environments

Chances are that you might work with several environments in Postman, and that where it’s useful to create environment variables. For example create an environment like shown below:

image

That way you can select which environment you want to work with when running queries, and when referencing variables use “{{ .. }}”. For example under Get New Access Token, change to this:

image

Now, lets finalize this blog post by logging in with another guest account, I will choose my Gmail account, I’ve already set up Google Federation and invited this user to my tenant.

First I need to clear the cookies:

image

Next I will click to Get a New Access Token again, and then authenticate as my Google account, which directs me to the Google login page:

image

After successfully authenticating, and using the new Access Token in the Authorization Header, I can run the basic /me query again, this time showing me that I’m now authenticated to Graph with my Gmail user:

image

And looking inside the Access Token again, I can see that the e-mail address is my gmail and the idp is now google.com:

image

If I had logged on with a Microsoft Account the idp value would have been “live.com”.

Next steps

So, now you know how to authenticate to and query Microsoft Graph with an Azure AD B2B Guest User. I really hope this functionality will come to Graph Explorer eventually, but for now Postman is already an awesome free tool for organizing and running your Microsoft Graph queries that I use a lot myself.

The Microsoft Graph Team has also published this source for a lot of useful collections of Graph queries:

https://github.com/microsoftgraph/microsoftgraph-postman-collections

Azure AD B2B Users and Access to Azure AD Application Proxy Apps

The purpose of this blog post is to show a practical approach and some guidelines for publishing Azure AD App Proxy applications to guest users using Azure AD B2B.

To keep this blog post short and to the point, I will make the following assumptions:

Demo scenario

I will first give a quick overview over the demo scenario for this blog post:

  • I will use my tenant elven.onmicrosoft.com, where I have configured a custom domain elven.no.
  • I have invited an external user: jan.vidar.elven@skill.no to the elven.onmicrosoft.com tenant. This user has accepted the invitation and can access resources that will be shared.
  • I have published some App Proxy applications, and in this scenario I will use Cireson Portal, which is a Self Service Portal for SCSM.

In this blog post I will use both single sign-on disabled with forms based authentication, and single sign-on with windows integrated authentication for this guest user, but lets first verify that the guest user can log on to my application panel.

Using Azure AD Access Panel as Guest User

When I log on to the Azure AD Access Panel at https://myapps.microsoft.com as external account I will se all my published applications at my company Skill AS, and since I have been added as a Azure AD B2B guest to the Elven Azure AD tenant, I can switch to that tenant like this:

image

I will then be redirected to the Elven Azure AD tenant and all my published applications will show (but for now this is none):

image

So lets start by adding this external guest to a published application without single sign-on and Windows Integrated Authentication enabled.

Without Single Sign-On

First, this is the guest user I will add to the application:

image

Then I go to the App Proxy Application, and in the properties I have required that any user must be assigned to access the application:

image

Under Application Proxy I will require pre authentication with Azure AD, so that users can not access the URL without being logged on to the tenant (in this case as a guest):

image

In this first scenario single sign-on with Azure AD and Windows Integrated Authentication is disabled:

image

Then I add my guest user as an assigned user to the application:

image

In the meantime I have configured the Cireson Portal to use Forms Based Authentication, and now we can test the guest user:

In the Access Panel my guest user can now see and launch the Cireson Portal published application:

image

And my guest user can successfully get to the web application which now presents a user login form, which will require a on-premises AD user with access rights to the Cireson Portal.

image

In my on-premises AD I have created just that, a user with the account name jan.vidar.guest:

image

And I can successfully log on with the guest user:

image

So far we have seen that an Azure AD B2B user can successfully launch an Azure AD App Proxy application, and in the next step log on with a local AD user with access to the application.

I the next section we will see how we can provide single sign-on with Azure AD and Windows Integrated Authentication.

PS! I will also change the Cireson Portal to use Windows Authentication before this next step!

Azure AD Single Sign-On and Windows Integrated Authentication

First I will need to change the settings for the Azure AD App Proxy application.

Under Single sign-on I will change to Integrated Windows Authentication, specify a SPN for Kerberos Constrained Delegation, and specify to use User principal name for delegated login identity:

image

By now you might have realized that for single sign-on to work with windows integrated authentication in a Azure AD B2B guest user scenario, you will need to have a “shadow” AD user for this external scenario. In my first test above, I had created a “jan.vidar.guest” user. Remember that I chose to use User principal name as a delegated login identity. So I will need a UPN that will be a link between my Azure AD guest user account (jan.vidar.elven@skill.no) and the local AD user. If that link is missing, you will see the following in the Application Proxy Connector Log:

image

So this error message tells us exactly what user principal name is expected from the guest user. The error message below provide more details from this error:

Web Application Proxy encountered an unexpected error while processing the request.
Error: The user name or password is incorrect.
(0x8007052e)

Details:
Transaction ID: {00000000-0000-0000-0000-000000000000}
Session ID: {00000000-0000-0000-0000-000000000000}
Published Application Name:
Published Application ID:
Published Application External URL:
https://selfservice-elven.msappproxy.net/
Published Backend URL:
http://azscsmms3/
User: jan.vidar.elven_skill.no#EXT#@elven.onmicrosoft.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299
Device ID: <Not Applicable>
Token State: NotFound
Cookie State: NotFound
Client Request URL:
https://selfservice-elven.msappproxy.net/Home/NavigationNodes
Backend Request URL: <Not Applicable>
Preauthentication Flow: PassThrough
Backend Server Authentication Mode: WIA
State Machine State: OuOfOrderFEHeadersWriting
Response Code to Client: 500
Response Message to Client: Internal Server Error
Client Certificate Issuer: <Not Found>
Response Code from Backend: <Not Applicable>
Frontend Response Location Header: <Not Applicable>
Backend Response Location Header: <Not Applicable>
Backend Request Http Verb: <Not Applicable>
Client Request Http Verb: POST

So, lets change the UPN of my local shadow user to that. You can either add the UPN suffix to your Active Directory Forest, or change the user principal name with AD PowerShell like:

Set-ADUser jan.vidar.guest -UserPrincipalName jan.vidar.elven_skill.no#EXT#@elven.onmicrosoft.com

image

Generally you will need to add Azure AD B2B users with user principal name in the form of:

<emailalias>_guestdomain#EXT#tenantdomain

So, lets try to launch the Cireson Portal again now, this time with Azure AD Single Sign-On and Windows Integrated Authentication:

image

And now the user will be logged directly into the Cireson Portal with SSO:

image

So now we have seen that we can successfully use Azure AD B2B Guests in an Azure AD Application Proxy published application scenario, with or without Single Sign-On, and that we require a link with the delegated identiy with a “shadow” user in the on-premises AD.

NB! Before you think that you should create that user as a disabled account, this is what happens:

image

This means, you have to enable the AD user account, but the password can be anything and don’t have to be shared with the external user.

Update: Require MFA from Guest Users

I have had some questions on how requiring MFA would affect guest users when accessing published applications, and decided to update the blog post on this.

First of all you would need to create an Azure AD Conditional Access Policy where you:

  • Target the policy to your guest users, for example by creating a group (assigned or dynamic) with all guest users in your tenant.
  • Target the policy to your selected published Azure AD App Proxy Apps.
  • Setting the policy to require MFA.

Your guest users will have to set up their security verification methods in your tenant before they can authenticate with MFA as guests to your published application. They will be prompted to do that if they haven’t done it before at first time, but they can also do that by accessing their profile in your tenants myapps.microsoft.com. See below picture where my guest user can set up preferred methods for MFA in the elven tenant:

MFAGuest4

In this example I have set up Microsoft Authenticator on my mobile phone, and note the #EXT# identity which is the guest user for Elven tenant:

MFAGuest2

I can the select to launch the application as a guest user, and will be prompted authenticate with my selected method for MFA:

MFAGuest3

In my mobile phone I can approve, again I can see that I authenticate with my #EXT# guest account (most text in Norwegian, but you get the idea;)

MFAGuest1

See notes under for license requirements for MFA and guest users.

Notes and tips

Although Azure AD B2B is a free feature, creating local users in Active Directory and accessing resources like web servers, database servers and any third party applications you publish are not free and you will have to check your licensing requirements.

You shouldn’t synchronize your shadow guest users to Azure AD with Azure AD Connect.

Using Azure AD Conditional Access for require MFA is an Azure AD Premium feature, so you need EMS E3 or Azure AD Premium P1 licenses. You can then use up to 5 Azure AD B2B guests per EMS E3/AADP1 license you own, in a 1:5 ratio. So for example if you internally have 100 EMS licenses, you can require MFA for up to 500 Azure AD B2B guests.

And finally, Microsoft has noted that there will be guidance and documentation coming for best practice and governance for these Azure AD and on-premises AD guest users, as there can be a lot more complex enviroments than my example here, see this link: https://techcommunity.microsoft.com/t5/Azure-Active-Directory-B2B/AAD-Application-Proxy-and-B2B-Users/td-p/85249