Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Using Azure B2C for multiple Domain based users #149

Open
LukeDuffy98 opened this issue Jul 23, 2021 · 30 comments
Open

Using Azure B2C for multiple Domain based users #149

LukeDuffy98 opened this issue Jul 23, 2021 · 30 comments
Labels
enhancement New feature or request In-Testing Feature in testing required feedback

Comments

@LukeDuffy98
Copy link

Hi

I am having issues trying to progress learner into the lti assignment. I have set up the course and added modules from MS learn without issue.

As a learner when i go to complete the work by clicking in the link

image

I then receive the following error

image

The user is signed in via Azure AD B2C Connect. The user is in a different tenant than our moodle.

If I use oidc OpenID Connect I receive an error
AADSTS50020

Sorry, but we’re having trouble signing you in.

AADSTS50020: User account '[email protected]' from identity provider 'https://sts.windows.net/00000-8edb-4464-8adc-4611b76ffab1/' does not exist in tenant 'xxx' and cannot access the application 'xxxx-4ed0-4534-b51d-8850917a2dc2'(AAD Moodle) in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account.

The App registration is set up as multitenant

image

Short of adding every user as a guest account I dont know how to get past this issue.

Thanks

@leestott
Copy link
Contributor

@LukeDuffy98 So the issue is the Learn LTI application is using the AAD to validate the user.

From what I understand the students are in a different AAD?

If this is the case you will need to assign all the users permissions to the app https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/assign-user-or-group-access-portal

@LukeDuffy98
Copy link
Author

Thanks Lee

I think the issue here is also connected to this one:
microsoft/o365-moodle#1738

It appears that all users must exist as a regular or guest in my AAD to use the tool.
Is that correct ?

@leestott
Copy link
Contributor

@LukeDuffy98 what extension are you using for moodle? I would recommend the OpenID Connect extension to allow AAD user to auth to Moodle

see https://moodle.org/plugins/auth_oidc#:~:text=The%20OpenID%20Connect%20plugin%20provides%20single-sign-on%20functionality%20using,Moodle%20and%20other%20OpenID%20Connect%20providers%20as%20well.

@LukeDuffy98
Copy link
Author

Hi Lee

That's the plugin I am using. For good measure I just reinstalled it.

For my own sanity s it true that all users must exist as a regular or guest in my AAD to use the tool ??

I'm not sure if I am trying to make something happen that just wont work.

Thanks again

@leestott
Copy link
Contributor

@LukeDuffy98 so typically if you have two AAD which aren't related but want to auth users on a single app you would use Azure B2C on the App https://azure.microsoft.com/services/active-directory/external-identities/b2c/#overview you would then simply point your App Auth to use the B2C connector.. Is this what your doing?

A Diag would help explain what your trying to do.

@leestott
Copy link
Contributor

leestott commented Jul 27, 2021

@LukeDuffy98 see https://moodle.org/mod/forum/discuss.php?d=388317 you will need to install the Learn LTI Application into the Azure B2C so that the app can give access to the users of each AAD.. At present it looks like you have the app installed within only one tenant so users in the other tenant do not have access to the app.

@LukeDuffy98
Copy link
Author

Thanks Lee

I am having a look now, but it seems I am back to the same issue when I try to access the LTI tool. Logging in is ok

image

@LukeDuffy98
Copy link
Author

Hi Lee

I don't know what I am missing to make B2C work with LTI.
Does it work with B2C and LTI ? If so do you have any step by steps I can follow ?

Thanks

@leestott
Copy link
Contributor

@LukeDuffy98 So which Dir is the App and App Service principal installed in?

You need to register the Learn LTI in your B2C see https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=app-reg-ga

@LukeDuffy98
Copy link
Author

Hi Lee

I have tried for a few days now to see if I can make it work, but still no joy.

The app and the app service principals are in the same directory.

At a high level the steps are :

  1. Create a new Azure B2C tenant
  2. Create and assign subscription to new tenant
  3. create new global admin user
  4. register web app for auth and add client secret etc
  5. run the run,bat file to deploy the LTI tool, signing in to the new B2C tenant
  6. configure LTI tool as per instructions

At this point any users in the B2C tenant can use the LTI tool no problem. Anyone outside still gets the error "Selected user account does not exist in tenant"

I would really love some help to solve this.

Thanks again

@leestott
Copy link
Contributor

leestott commented Aug 2, 2021

@leestott leestott changed the title Selected user account does not exist in tenant - AADSTS50020 Using Azure B2C for multiple Domain based users Aug 2, 2021
@leestott
Copy link
Contributor

leestott commented Aug 2, 2021

@LukeDuffy98
The issue is the Learn LTI Application is registered within the AAD Tenant so only users within that Tenant have access to those resources https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals and you need to setup Application multitenant identity https://docs.microsoft.com/en-us/azure/architecture/multitenant-identity/

In this guidance, we'll look specifically at using Azure AD for identity management.

If you have on-premises Active Directory you can use Azure AD Connect to sync your on-premises Active Directory with Azure AD. If your on-premises Active Directory cannot use Azure AD Connect (due to corporate IT policy or other reasons), the SaaS provider can federate with the customer's directory through Active Directory Federation Services (AD FS). see https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant

@leestott
Copy link
Contributor

leestott commented Aug 2, 2021

@LukeDuffy98
There are two main options here.

  1. Add the user to the tenant:

In this case you have to add the user to the tenant that the application is hosted in. You can follow this document https://docs.microsoft.com/en-us/azure/active-directory/b2b/b2b-quickstart-add-guest-users-portal#add-a-new-guest-user-in-azure-ad to add the user [email protected] as a Guest User to the tenant. And then you have to grant access to the application https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/methods-for-assigning-users-and-groups#assign-users for the said user.

  1. Make the application as a Multi-Tenant Application:

You can convert the application to accept users from multiple tenants. see https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant
In this way you can give access to users who are not in your tenant without having to add them to the tenant where the application is in. This document describes the between Single and Multi-Tenant Applications. Another good read http://www.andrewconnell.com/blog/azure-ad-what%E2%80%99s-the-difference-between-single-vs-multi-tenant on the same.

@leestott
Copy link
Contributor

leestott commented Aug 3, 2021

@LukeDuffy98

OK so you simply need to edit this file
https://github.com/microsoft/Learn-LTI/blob/main/client/src/Core/Auth/AppAuthConfig.ts

Line 11 authority: https://login.microsoftonline.com/${process.env.REACT_APP_EDNA_TENANT_ID},

to authority: https://login.microsoftonline.com/common/${process.env.REACT_APP_EDNA_TENANT_ID},

see https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant for other details

@leestott
Copy link
Contributor

@LukeDuffy98
So please look at this best practice for making the application support this scenario https://docs.microsoft.com/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant

There a few additional changes you will need to make this is a good overview video https://www.youtube.com/watch?v=Jfrp7DI7G0Q

@leestott leestott added the enhancement New feature or request label Aug 23, 2021
@leestott
Copy link
Contributor

leestott commented Sep 9, 2021

@LukeDuffy98

We have identified a work around which will solve your request on providing access to multiple domains which you own.

But we do not recommend you undertake a security review before implementing this solution

You will need to fork the repo and make the following changes on your fork end after cloning the repository and then deploy the solution from your forked repo..

Note – These steps are not a workaround for proper Multi-Tenant behavior.

It is only a workaround for the above customer issue as the mentioned this in the comments - we use an entirely different azure tenet/account for our servers than from what we use to manage users.

Steps:
• In the Install-Client.ps1 file, Replace REACT_APP_EDNA_TENANT_ID="$(Get-TenantId $AppId)"; with REACT_APP_EDNA_TENANT_ID="TID"; where TID is the tenant id with intended users
• In the azuredeploy.json file, Remove line no.143 , "issuer": "[concat('https://sts.windows.net/', variables('tenantId'), '/')]"
• In the azuredeploy.json file, update line no.234 with the user email address of the admin from the tenant (TID), "AllowedUsers": "user@newTenant",
• Run the deployment script.
• Make the app multitenant in the azure portal.
• While Creating platform registration, login with with upn from tenant TID

@warrenbuhler
Copy link
Contributor

Hi @LukeDuffy98 ,

Would you be interested in testing out a change to the LTI that would support multi-tenant sign-on using Azure Business to Consumer?

I'm part of a UCL team that has been working with Lee at Microsoft to support multi-tenancy. We are finalizing a forked repo and expect to have it ready for testing within 1.5 - 2 weeks (early August). We have done all our testing using Moodle which we have confirmed supports B2C authentication already.

You will need
• A B2C tenant -- you will need create one, but we have a script to help configure the remaining settings
• An LMS for testing (preferably Moodle)
• Two or more AD tenants to whitelist as part of testing

We are scripting as much of the setup and configuration as we can. So we expect the total work on your end to be about than 3 -7 hours, obviously changing based on how much testing you do.

If you are interested, I will reach back out on Github here when our changes are ready. We will have documentation ready and a form for you to fill out feedback on. We can also correspond on this issue thread if you have any issues, questions, or concerns.

Best,

Warren and the UCL Team

@LukeDuffy98
Copy link
Author

LukeDuffy98 commented Jul 20, 2022 via email

@warrenbuhler
Copy link
Contributor

warrenbuhler commented Aug 4, 2022

Hi @LukeDuffy98 ,

Our change to the LTI to support Azure Business to Consumer is ready for others to test. It is working for us, so we'd love for you to check it as well and give us any feedback you have!
Github Link: https://github.com/UCL-MSc-Learn-LTI/Learn-LTI

If you have time in the next couple weeks to deploy and give us feedback, we should have time to make changes before our program ends.

We have extensive readmes and documentation to support the workflow but at a high level:

  • In Azure, create a B2C tenant (must be manually done and must have the onmicrosoft domain name)
  • Run the deploy script
  • Select to also configure a B2C tenant - This will create the needed application registrations, secrets, etc for you
  • Continue to run the normal LTI deploy
  • Complete the normal LTI configuration and setup on the platforms page
  • Try logging into LTI with users from different tenants and ensure it works!

You can put any feedback you have for us here, or if you'd prefer a online form we can create one!.

We've also created a forked branch of a Moodle plugin to support B2C authentication with our custom policies that you can use to enable B2C authentication into Moodle.
https://github.com/UCL-MSc-Learn-LTI/moodle-auth_azureb2c

If you run into any trouble, please reach out to us and we can troubleshoot asynchronously or hop on a call!

Best,

Warren

Ps our version currently makes the keyvaults without soft deletion or purge protection for easier deletion during testing. If you decided to move forward with this branch, we will be turning those protections back on later.

@LukeDuffy98
Copy link
Author

LukeDuffy98 commented Aug 8, 2022 via email

@warrenbuhler
Copy link
Contributor

Hi @LukeDuffy98 ,

If you'd like, we could jump on a Teams or Zoom call to take a look together. That might be the fastest option for resolving this. We are free the next hour, or could meet Tuesday Morning UK time or anytime Wednesday. Happy to set one up if that works for you!

I can't actually see any error message in your github post. Not sure if pasting the error message failed, or if it just isn't rendering properly

Best,

Warren

@warrenbuhler
Copy link
Contributor

@LukeDuffy98 , if you also could upload the log and transcript file from your deployment we could take a look at that ahead of time.

@LukeDuffy98
Copy link
Author

Thanks for your help @warrenbuhler
So I started again with a new b2c tenant .

A couple of errors appear. I have attached the log and transcript:

Issue 1

B2C STEP 1: Create AD application

Please login to your AD tenant for this subscription via the pop-up window that has launched in your browser
Creating the client secret for b2c_AD_app
Granting permissions to the AD application
Creating service principal for b2c_AD_app
Granting permissions to the service principal for b2c_AD_app
ERROR: The command failed with an unexpected error. Here is the traceback:
ERROR: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Traceback (most recent call last):
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\urllib3/connectionpool.py", line 699, in urlopen
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\urllib3/connectionpool.py", line 445, in _make_request
File "", line 3, in raise_from
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\urllib3/connectionpool.py", line 440, in _make_request
File "http\client.py", line 1374, in getresponse
File "http\client.py", line 318, in begin
File "http\client.py", line 287, in _read_status
http.client.RemoteDisconnected: Remote end closed connection without response

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\requests/adapters.py", line 439, in send
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\urllib3/connectionpool.py", line 755, in urlopen
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\urllib3/util/retry.py", line 532, in increment
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\urllib3/packages/six.py", line 769, in reraise
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\urllib3/connectionpool.py", line 699, in urlopen
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\urllib3/connectionpool.py", line 445, in _make_request
File "", line 3, in raise_from
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\urllib3/connectionpool.py", line 440, in _make_request
File "http\client.py", line 1374, in getresponse
File "http\client.py", line 318, in begin
File "http\client.py", line 287, in _read_status
urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\knack/cli.py", line 231, in invoke
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/init.py", line 663, in execute
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/init.py", line 726, in _run_jobs_serially
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/init.py", line 718, in _run_job
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/command_modules/role/commands.py", line 51, in graph_err_handler
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/init.py", line 697, in _run_job
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/init.py", line 333, in call
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/command_operation.py", line 121, in handler
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/command_modules/role/custom.py", line 882, in add_permission
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/command_modules/role/_msgrpah/_graph_client.py", line 105, in application_update
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/command_modules/role/_msgrpah/_graph_client.py", line 52, in _send
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/util.py", line 985, in send_raw_request
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\requests/sessions.py", line 655, in send
File "D:\a\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\requests/adapters.py", line 498, in send
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
To open an issue, please run: 'az feedback'

Issue 2 -
Press enter when ready to continue after recording the client secret:
A web browser has been opened at https://login.microsoftonline.com/706c4199-f5c7-4b90-b45b-84f5ca1d9811/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with az login --use-device-code.
[
{
"cloudName": "AzureCloud",
"homeTenantId": "706c4199-f5c7-4b90-b45b-84f5ca1d9811",
"id": "3883a4dc-062f-4f8f-b4ef-fcebd79afd7f",
"isDefault": true,
"managedByTenants": [],
"name": "Azure Pass - Sponsorship",
"state": "Enabled",
"tenantId": "706c4199-f5c7-4b90-b45b-84f5ca1d9811",
"user": {
"name": "[email protected]",
"type": "user"
}
}
]
argument --subscription/-s/--name/-n: expected one argument

Examples from AI knowledge base:
az account set --subscription mysubscription
Set a subscription to be the current active subscription. (autogenerated)

az account list
Get a list of subscriptions for the logged in account. (autogenerated)

az account show
Get the details of a subscription. (autogenerated)

https://docs.microsoft.com/en-US/cli/azure/account#az_account_set
Read more about the command in reference docs

=============================================================
STEP #3 - Choose Location

Issue 3

STEP #12 - Installing the client

npm WARN deprecated [email protected]: Please update to latest patch version to fix memory leak isaacs/node-lru-cache#227
npm WARN deprecated [email protected]: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
npm WARN deprecated [email protected]: See https://github.com/lydell/source-map-resolve#deprecated
npm WARN deprecated [email protected]: This SVGO version is no longer supported. Upgrade to v2.x.x.
Finished[#############################################################] 100.0000%
Client App Published Successfully

Issue 4
When trying to access https://learnclientixxjyxpf6.z8.web.core.windows.net/platform
It goes through AAD authentication, giving a blank page, but dev tools displays this error
main.565f4574.js:2

   ServerError: invalid_request: AADB2C90238: The provided token does not contain a valid issuer. Please provide another token and try again.

Correlation ID: a2b84abf-03e4-4b80-b81f-1fcd3d36d62c
Timestamp: 2022-08-08 23:13:59Z

at t [as constructor] (main.565f4574.js:2:391518)
at new t (main.565f4574.js:2:449244)
at e.validateServerAuthorizationCodeResponse (main.565f4574.js:2:529551)
at t.handleFragmentResponse (main.565f4574.js:2:536155)
at t.<anonymous> (main.565f4574.js:2:631375)
at main.565f4574.js:2:406218
at Object.next (main.565f4574.js:2:406323)
at main.565f4574.js:2:405258
at new Promise (<anonymous>)
at _a (main.565f4574.js:2:405003)

Transcript-09-08-2022-08-49-53.log
Log-09-08-2022-08-49-53.log

@warrenbuhler
Copy link
Contributor

Hey @LukeDuffy98 ,

We've taken a look and have some thoughts / suggestions. In short

Issue 1:
We haven't seen this issue before. The disconnect appears to have been while it attempts to set the correct permissions status on the "email" and "profile" permissions. It is possible this was a networking issue, and we could look into putting in more defensive programming if this issue is common and actually leads to probleems

Our working deploy looks like this on the AD tenant - app registration "b2c_AD_app" - API permissions blade

image

Can you check whether the status shows "Granted"

Issue 2:
We've fixed the code throwing this message. However, we believe the error was functionally benign and didn't cause the later authentication issues.

Issue 3:
These npm warnings do not cause any problems in deployment or operation and exist on the current version of the deploy scripts. We'd like to fix them if we have time, but they similarly shouldn't have caused any authentication issues.

Issue 4:
This one is obviously a hard stop. We have only seen this error when trying to complete a B2C login from a non-whitelisted tenant. Can you confirm that you are logging in as a user whose home tenant is one of these tenants?

It looks like you used: "user":{"name":"[email protected]","type":"user"}

And you whitelisted:
Important - if no tenants are whitelisted; nobody will be able to access the AD
Tenant with ID bdef9bb6-31a1-4d1f-bd33-672f09621c5e added to the whitelist
Tenant with ID 6a450216-13ff-486c-8de5-6bbef7b20ae2 added to the whitelist

If the user is from a whitelisted tenant, then we will need to do more digging wih you.

We will look into ways to make the error thrown more obvious.

Best,

Warren

@LukeDuffy98
Copy link
Author

Thanks Warren. I ended up having to reset the AllowedUsers config setting to allow access to the platform settings.

So all good now in accessing that.

Now I'm back to the same place as the other night, when i attempt to login. I end up back at the redirect page https://xxx.com/auth/azureb2c/ with the following information (this is what didnt appear in the original email screenshot):

Error in Azure AD B2C Connect. Please check logs for more information.

More information about this error

Debug info:
Error code: errorazureb2ccall×Dismiss this notification
Stack trace:
line 47 of /auth/azureb2c/classes/utils.php: moodle_exception thrown
line 256 of /auth/azureb2c/classes/azureb2cclient.php: call to auth_azureb2c\utils::process_json_response()
line 221 of /auth/azureb2c/classes/loginflow/authcode.php: call to auth_azureb2c\azureb2cclient->tokenrequest()
line 107 of /auth/azureb2c/classes/loginflow/authcode.php: call to auth_azureb2c\loginflow\authcode->handleauthresponse()
line 105 of /auth/azureb2c/auth.php: call to auth_azureb2c\loginflow\authcode->handleredirect()
line 29 of /auth/azureb2c/index.php: call to auth_plugin_azureb2c->handleredirect()

@danielmusselwhite
Copy link

danielmusselwhite commented Aug 10, 2022

Hey @LukeDuffy98

Just clarifying:

  1. the platform page now works correctly
  2. the current issue is that when users try to login to Moodle via the Azure AD B2C Connect button it redirects to https://xxx.com/auth/azureb2c/ with the debug errors listed n your above comment

If so, would it be possible if you could send me the values you configured on the platform page/ moodle setup (here and here),

Am currently looking into the issue in the codebase but would also be worth just verifying the values used in the setup of the environment.

@LukeDuffy98
Copy link
Author

LukeDuffy98 commented Aug 10, 2022

If its easier you can email me
Screenshot below

image

@LukeDuffy98
Copy link
Author

Hi Daniel

Just sent you an email

@leestott
Copy link
Contributor

leestott commented Aug 23, 2022

Thanks to @LukeDuffy98 for working with @warrenbuhler on the test AAD + B2C connectivity enhancement the team at University College London have this fork for testing https://github.com/UCL-MSc-Learn-LTI/Learn-LTI

@leestott
Copy link
Contributor

Confirmed the AAD + B2C features work by @LukeDuffy98

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request In-Testing Feature in testing required feedback
Projects
None yet
Development

No branches or pull requests

4 participants