Azure AD B2C with Microsoft account and Sign in user - azure

I am getting this error when configuring an asp.net core app to use Azure AD B2C authentication with Microsoft Account as external identity provider.
AADSTS70000121: The passed grant is from a personal Microsoft account and is required to be sent to the /consumers or /common endpoint.
As per my findings on SO and Microsoft documentation on the same, it points to use following as authority
in appsettings.json:
"Authority": "https://login.microsoftonline.com/common",
The common endpoint is suggested by Azure AD b2c
documentation when you use Microsof Account as an identity provider.
While registering an application in Azure AD b2c tenant, I use following as Supported account types:
Accounts in any identity provider or organizational directory (for authenticating users with user flows)
So seems all is configured properly but still error suggest that I am not using common endpoint which in fact I am using it.
Links I followed:
How to acces AzureRM with a AzureAD Multi-Tenant App using personal Microsoft account?
Error getting SAML Metadata for Azure AD B2C Policy - AADB2C90022

Related

What approaches are available for allowing Azure AD B2C users to GET and POST data to a M365 environment via Graph API?

Per the docs, there is no 'out of the box' way to enable Azure AD B2C users to interact with the M365 environment associated with the Azure AD tenant that was used to create the Azure AD B2C tenant.
Azure AD B2C can't be used to authenticate users for Microsoft 365.
Source:
Can I use Azure AD B2C to provide social login (Facebook and Google+) into Microsoft 365?
But I still need to be able to provide this functionality, i.e GET and POST requests to M365 via the Graph API.
To be clear, this is what I have achieved so far:
Azure AD B2C users can login
Azure AD users can login and interact with their own M365 environment via Graph API
(to enable this, I added the Azure AD tenant as an identity provider, per this article)
What I have not yet been able to figure out is:
How can the Azure AD B2C users interact with the M365 environment associated with the Azure AD tenant?
(that created the Azure AD B2C tenant)
To illustrate a use case for this requirement:
Company_A wants to enable external contractors to be able to submit compliance documents to them
They set up Azure AD B2C and create accounts for their external contractors
They set up a Node.js/Express web app on Azure
External contractors can now login to a web app and view forms designed to submit data and attachments
How can those forms send data and attachments to a Document Library in Company_A's M365 environment?
I have been pondering this issue for a while and can't conceptualise a mental or technical model of how this can be achieved.
Google searching related phrases doesn't produce any relevant content.
I am hoping someone will have the knowledge and experience to be able to say:
You will need to follow THIS paradigm which is documented HERE and involves doing THIS
Edit:
I am reading articles like these:
Get access without a user
which talks about scenarios where:
apps that have a signed-in user present may also need to call Microsoft Graph under their own identity
and contemplating adding Application Permissions (as opposed to Delegated Permissions) to my Azure AD B2C application registration.
Just to test the idea, I have added Sites.ReadWrite.All as an Application Permission and granted Admin Consent for that permission. How would I define this scope (Sites.ReadWrite.All) to be associated with the 'home' Azure AD tenant (as opposed to the Azure AD B2C tenant)? I am using msal-node which has a method named getAuthCodeURL() where you pass through the scopes required. I am assuming if I just added Sites.ReadWrite.All it would default to being applied to the Azure AD B2C tenant, rather than the desired Azure AD tenant?
M365 doesn’t exist in an Azure AD B2C tenant, you cannot apply a license for Office there. This simply isn’t possible.
For Graph API, you cannot use B2C issued tokens to call it. You must use underlying AAD Tokens to access it. Your server would need to perform Azure AD client credentials flow against the Azure AD endpoint of your AAD B2C tenant and ask for a token to Graph API. https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
Microsoft service scopes only apply to the underlying Azure AD endpoints of your AAD B2C tenant. They won’t mean anything at the AAD B2C login endpoints. Hence, the differentiation is made by the endpoint used.
An Azure AD B2C tenant has both endpoints:
AAD: login.microsoftonline.com/tenantId
B2C: b2clogin.com/tenantId
Since M365 env does not exist for B2C tenants, the MS Graph API is only useful to R/W user data. But, for this, you could just use the B2C user flows to R/W user profile data, and return user profile data into the B2C token, so you don’t have go call MS Graph API. This is actually the intended usage pattern.

How to login with corporate account when using Microsoft Account identity provider in Azure AD B2C?

I want to build an application where users can log in with their corporate Microsoft / Azure AD account.
For that, I created a Azure AD B2C incl. SignUpSignIn user flow with the "Microsoft Account" identity provider.
Now when I want to log in I get redirected to https://login.live.com/ and can successfully log in with my personal microsoft account. However, if I enter the email address of my corporate account, the error message "This microsoft account is not available" comes up.
The signInAudience of my app registration is set to AzureADandPersonalMicrosoftAccount. So I would expect that also corporate accounts should work?
"Microsoft account" there refers only to personal Microsoft accounts (Outlook/Live/Hotmail accounts).
If you want to only authenticate with one Azure AD tenant, there is guidance for adding that as an identity provider: https://learn.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-azure-ad-single-tenant?pivots=b2c-user-flow.
Multi-tenant Azure AD authentication could be done with the generic OpenID Connect provider I think: https://learn.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-generic-openid-connect?pivots=b2c-user-flow
It can also be achieved through custom policies: https://learn.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-azure-ad-multi-tenant?pivots=b2c-custom-policy.

How can I use idp_access_token returned by azure b2c service

I have setup a azure ad b2c service to sign up/ sign in my users and have used third party identity providers google and microsoft. After successful logging in, I get idp_access_token
back from b2c service. Can I use this token to directly connect to google and microsoft api
as azure docs mention, this token is issued by identity providers and returned as claims by b2c service. But the idp_access_token doesn't seem to be a valid access token and no claims are included in it.
To get a valid "idp_access_token", please check if you have to set "v2.0" in the metaurl of the OpenId Identity Provider Configuration:
https://xxx.b2clogin.com/xxxx.onmicrosoft.com/v2.0/.well-known/openid-configuration
We maynot be able to edit metadeta url of already created one .So try create new one with "v2.0" in metaurl.
When a user signs with identity provider, like google or Facebook, your app gets the identity provider's access token passed in Azure AD B2C token.This idp_access_token can be used call the identity provider’s API, such as the Facebook Graph API i.e;Usually the embedded IdP access token is used to call the services that the IdP hosts. For details see Pass an access token through a user flow to your application in Azure Active Directory B2C.
Reference: techcommunity.microsoft.com blog
Note :
Azure AD B2C supports passing the access token of OAuth 2.0 identity providers, which include Facebook and Google. For all other identity providers, the claim is returned blank.
Even if idp_access_token claim is a valid JWT, it cannot be used to access Microsoft Graph or other additional scopes. As usually the
embedded IdP access token is used to call the services that the IdP
hosts. But Microsoft Graph data is hosted in Azure AD and not in
Microsoft Account side.
You can check this microsoft document to Set up sign-up and sign-in with a Facebook account using Azure Active Directory B2C or with a Google account using Azure Active Directory B2C
References:
Using Azure B2C login to access Microsoft Graph is the social login is a Microsoft account

Login from Microsoft account not working for Multitenant Azure AD application

I'm building multitenant SaaS web based application. Application is registered in my tenant and each customer with their office 365 subscription will get Service principal object in Azure AD.
I'm having problem with login from external account (Microsoft account) in customer tenant.
I created example and tried to see what I can get from access token.
Sample consists from one client application (.js) that uses MSAL library to handle authentication and two APIs that have protected endpoints. I also created three separate Azure AD applications AlanClient, AlanAPI1, AlanAPI2. Both AlanAPI1 and AlanAPI2 have API exposed (Expose an API section in Azure Portal application) and have specified one consumer AlanClient. AlanClient has permission to both APIs. All applications are registered with "accessTokenAcceptedVersion": 2 and "signInAudience": "AzureADMultipleOrgs".
As far as I understood this should be enough to login with
Office 365 account from host tenant
Microsoft account that is registered as external user in host tenant
Office 365 account from guest tenant
Microsoft account that is registered as external user in guest tenant
Clarification:
- host tenant --> Azure AD instance in which application is registered. In error message bellow tenant A.
- guest tenant --> Azure AD instance that is only using application
I have a problem with case no. 4
I get this error message:
AADSTS50020: User account 'lovro.p365#...' from identity provider 'live.com' does not exist in tenant 'A' and cannot access the application AlanClient 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 AD user account.
The scenes of 2 and 4 should be the same.
I have tested both and everything is OK.
You could use OAuth 2.0 auth code grant flow to have a test with it.
Construct a request to login.microsoftonline.com with your app configurations.
This URL will look like:
https://login.microsoftonline.com/[tenant A]/oauth2/v2.0/authorize?client_id=[client id of the Azure AD app registered in host tenant]&response_type=code&redirect_uri=[redirect uri of the Azure AD app]&nonce=1234&resource=https://graph.microsoft.com.
After signing in with credentials of Microsoft Account in tenant A, you will get a "code" in the address bar. Use this code to request access token:
POST /[tenant]/oauth2/v2.0/token HTTP/1.1
client_id=[client id of the Azure AD app registered in host tenant]
&scope=https://graph.microsoft.com/user.read
&code=[code got from the previous step]
&redirect_uri=[redirect uri of the Azure AD app]
&grant_type=authorization_code
Then we could get the access token for Microsoft Account as a guest user in tenant A.

Azure AD B2C Token Issue

As an enterprise, we would like to use Azure AD B2C and we have internal and external users.
Azure AD helps us manage our Azure users, corporate users and we can even add users with x#.onmicrosoft.com emails.
When we wanted to use Azure AD B2C for our consumers. So we have 2 choices to add our users which is a local user and an external user (Facebook, Google, etc)
If the local user belongs to our corporate it is ok to create the user using the Azure AD B2C portal.
But when we try to create the Azure AD B2C users who have another kind of emails, we need to use our own app which is consuming the Graph API. (that is the Azure portal restriction)
The issue is we are having a hard time getting the users values after the login is they are local users with Gmail or x emails.
We are using MSAL to get the related information instead of ADAL.
We have enabled the scopes and also enabled the API Access but this is the errors we are getting.
Error 1:
acquiring the popup:
AADB2C90055: The scope 'openid email openid profile' provided in request must specify a resource, such as 'https://example.com/calendar.read'.
Correlation ID: 86d6ff41-1cef-4ba1-9b26-2aa281c92ccd
Timestamp: 2017-09-15 10:22:20Z
Error 2:
invalid_request Error during login:
AADB2C90117: The scope 'user_impersonation' provided in the request is not supported.
Correlation ID: 785c6487-cd7f-4750-a769-deb477cb4ba4
Timestamp: 2017-09-15 10:32:39Z
:invalid_request
Error 3:
Error acquiring the popup:
AADB2C90055: The scope 'email openid profile' provided in request must specify a resource, such as 'https://example.com/calendar.read'.
Correlation ID: bd714482-8534-473e-94bc-0a4c56da686d
Timestamp: 2017-09-15 10:36:15Z
:invalid_request
Error1 and Error3
There is no need to provide scope openid profile offline_access when we using MSAL library to interact with Azure AD B2C. The SDK will add there scope automatically. We only need to provider the custom scope we defined for the web API app register on Azure AD B2C blade.
Error2
The scope user_impersonation is an custom scope defined by the app by default. We should contain the app id URI(https://{myB2CTenant}.onmicrosoft.com/b2capp2) before it like below:
string[] SCOPES = { "https://{myB2CTenant}.onmicrosoft.com/b2capp2/note_read", "https://{myB2CTenant}.onmicrosoft.com/b2capp2/user_impersonation" };
And AFAIK, the Azure AD B2C doesn't support delegate the user to access the Azure ad Graph at present. We need to register an app via Azure Active Directory->App registrations(not in Azure AD B2C blade) and access the Microsoft or Azure AD Graph via the client credentials flow. Here is a helpful link calling the Graph API in Azure AD B2C:
Azure AD B2C: Use the Graph API
If you want the Azure AD B2C app also support delegating user to calling the Microsoft Graph, you may submit the feedback from here.
For me that error meaned, that I am trying to aquire a accesToken when not having a valid idToken.
So make sure you have a valid idToken before calling acquireTokenSilent().

Resources