How to access Email of an User on B2C using Graph API - azure

I want to know the email address of a user to send an email.
On my application, people can sign up with social accounts (google/facebook/Microsoft) or local accounts.
When creating a local account we use the email.
I found this info about how email is stored.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-policies
Email address storage: An email address can be required as part of a user flow. If the user authenticates with a social identity
provider, the email address is stored in the otherMails property. If a
local account is based on a user name, then the email address is
stored in a strong authentication detail property. If a local account
is based on an email address, then the email address is stored in the
signInNames property. The email address isn't guaranteed to be
verified in any of these cases. A tenant administrator can disable
email verification in the basic policies for local accounts. Even if
email address verification is enabled, addresses aren't verified if
they come from a social identity provider and they haven't been
changed. Only the otherMails and signInNames properties are exposed
through the Active Directory Graph API. The email address in the
strong authentication detail property is not available
Not sure why the field "Mail" on the user is not being used... but using GraphApi:
I make a GET: https://graph.microsoft.com/v1.0/Users?$select=displayName,mail,otherMails,signInNames
Some emails appear on "mail", others on the array of "otherMails", and "singInNames" can't be selected :( doesn't show any info, so are some users that I can't get the info about the email.
How can I solve this? Only using Azure AD Graph instead of Microsoft Graph API, since on that API signInNames are returned?
Isn't there any way of storing the emails always on the same property? Or at least one that I have access on Microsoft Graph API? Using Custom policies only with Claims transformation?

In the Microsoft Graph API you can use:
GET: https://graph.microsoft.com/v1.0/Users?$select=displayName,mail,identities,otherMails
You can find the email of a local account in the identities collection.
In the BETA version of the Graph API (graph.microsoft.com/beta) the identities and otherMails properties are also returned without a $select, in the v1.0 version only when specified in the $select.

I managed to get the email for a Azure B2C user through the following Microsoft Graph API call:
https://graph.microsoft.com/v1.0/users?$select=identities

You need to collect the email addresses from different places such as mail, otherMails and signInNames through AD Graph API. signInNames is NOT available in Microsoft Graph API.
Note that in the case where users sign in with username + email validation, there is no way to retrieve the email used.
Or you could add a custom attribute in custom policy, where you can require users to type in their email address. After that, you could use AD Graph to get the custom attribute (A sample here).

The Microsoft Graph is the successor of the old Windows Graph. The Microsoft Graph doesn't support the signInNames property for Users object anymore. One has to filter on identities instead. However identities isn't part of the default property set of the User object so one has to select it. Once that's done, one can filter on identities using an any clause.
Note that filtering on issuerAssignedId can only be done when both issuerAssignedId and issuer are used in the filter clause.
GET: https://graph.microsoft.com/v1.0/Users?$select=id,identities&filter=identities/any(c:c/issuerAssignedId eq '{email}' and c/issuer eq '{issuer}')

Related

How to get actual user email which he/she used for Azure AD SSO login?

I want to get the user emails used for Azure organization on callback action of SSO web login flow.
Could you please advise which property and which API permission should I request for it? I tried upn, preferred_username, and email properties, but as I understand they can differ from the actual email.
Tried multitenant and single-tenant approaches.
Keep in mind that the user logs in with their UPN, which is typically (but isn't necessarily) the same as their email address.
The email claim should contain the user's email address if the directory is looked after by admins. That's the one you're after.
More information on the default claim set can be found here.
More information on how the UPN might be populated, including the approach of using an Alternate ID can be found here.

Can't reset B2C account password create via the Graph API

Hoping someone can shed some light on the following matter;
I got an Angular & .Net core Web API application that uses Azure B2C to authenticate users.
User accounts are created by the users themselves via the signin/signup custom policy or administrator can create accounts via the app using the Graph API.
Due to the requirements, the app uses usernames (as opposed to email addresses) to log into the application. So far I've managed to get everything working except for the following scenario:
When an account is created via the Graph API, the owner of that account cannot reset the account's password. The error is "An account could not be found for the provided user ID".
This isn't the case for accounts that get created via the custom signup policy so I did some comparison and found that for those account that get created via the Graph API, the Email is missing (which can be found under User -> Authentication Methods). I looked at populating that field, but it appears the "Mail" attribute is 'read only' (not sure if that's the right attribute anyway).
At the moment I'm having to manually set the email via Azure so those account's passwords can be reset by their owner if necessary. This is obviously not ideal and wanted to see if there is anyone that might have gotten around this issue, or a least get confirmation that this is indeed a limitation of the Graph API.
Thanks in advance for your help
So I managed to get this working using the approach outlined by Jas Suri. These are the steps that I went through
Created a custom attribute in my B2C tenant to hold the account email address
Included the custom attribute claim type (extension_emailAddress) as well as the strongAuthenticationEmailAddress in the TrustFrameworkBase.xml
Updated my apps's custom policies to include the technical profile for local account discovery. I basically just copied the necessary bits and pieces from here
Updated the local account discovery to perform the comparison against the extenstion_emailAddres instead of strongAuthenticationEmailAddress.
Added an extra step to the Sign up user journey so that the value in strongAuthenticationEmailAddress is copied to extension_emailAddress
Updated my Web API / Graph API "create user" function so that it sets the extension_appidguid_emailAddress
That's it. Now it doesn't matter how the account gets created, the email address will be stored in the extension attribute and the password reset will be able to find the account using that attribute.
happy to provide more details if anyone comes across this.
The problem is as you’ve identified, the Sign Up policy uses the strongAuthEmail attribute to store the verified email for a username based account. The Password reset policy will use this to verify the user owns the username. When creating the user with graph api, you can’t populate this field, it’s not exposed. The only option is to use a custom policy which stores this secure email in an extension attribute, and your graph api created users can then also target the same attribute to allow the stars to align.
Mail attribute is not the same as the Email under Authentication Methods, and currently there is no such graph api to set the Email value under Authentication Methods.
By the way, there is no need to create Azure AD B2C user for a user as users can sign up themselves.

Azure B2C local account Sign Up with Username - How to get the username suggestion

I have 2 questions:
As per the client requirement, while Sign Up using Azure B2C UI flow (signInNames – Type is userName), user should get suggestions for username once they entered some value in username field(on the basis of existing usernames in B2C AD).
How we can achieve this functionality?
Note: I am using B2C built in Sign Up policy.
Other requirement is that multiple user can have same Email Id (as we are already using signInNames – Type : userName ).
So once user enters the email Id and if that email Id is already associated with other username(s), we need to populate the list of usernames associated with the email. How we can achieve this functionality?
Any help is very much appreciated, I actually got stuck so please offer any suggestion.
You mean the "email address" property, right, not the actual email messages? If so, you should be able to use the /users endpoint: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/user_get
What is the resource you want to access via the access token ? If resource is https://graph.windows.net/,you could use Azure AD Graph API to get the email information of the signed-in user :
GET https://graph.windows.net/me?api-version=1.6
Authorization: Bearer yourAccessToken
If resource is https://graph.microsoft.com/,you could use Microsoft Graph API to get the email information of the signed-in user:
Get https://graph.microsoft.com/v1.0/me
Authorization: Bearer yourAccessToken
In response you could check UserPrincipalName claim value which is an email address that can receive emails.
For the username suggestion part, if you are talking about when you fill out the username form field and the chrome/IE box pops up above, that is cached at the client and you can't do that. If you are talking about the user tries to register with a username that is already taken and you want to give them suggestions you may, but I doubt it, be able to do it in a custom policy. More than likely, however, you would need to use a custom web application to do that as that is more of an advanced sign in journey.
The second part of your requirements would also need to be fulfilled within a custom web application as well, you can retrieve and access AD items within the custom user journey's but again this is more of an advanced sign in journey.

Azure AD B2C sign up policy additional emails

Is it possible to get Azure AD B2C to store alternate emails so we can help recover the account? I am using a signup policy that is based on a local account. I am not using username, I'm using "email" as the identifier.
Even though I specify the local account type as email and also specify a signup claim of email, it only let's me put in one email. I can see how that might make sense.
I tried just storing an additional email in one of the existing graph fields, but it said that was read only.
Along those lines, is it possible to have more than one email listed in the signInName array?
TIA

How to configure email address for a user in Microsoft Azure AD?

I have created a trial account for Microsoft Azure. In Azure Active Directory, I'm trying to create a new user, but I'm not seeing email address field. I see only username, firstname, lastname and display name fields. Will Azure treat username (like testuser#mydomain.onmicrosoft.com) as an email? or I'm I missing something? I didn't find much information in its documentation.
No, Azure AD will not assume that the username (known as "UserPrincipalName", in the Azure AD Graph API and Azure AD PowerShell module) is actually an email address that can receive emails.
If you would simply want a place to store a given user's email address (one that actually has a mailbox behind it), you can use the "Alternate Email Address" field in the Azure Portal (under "Profile" section for a given user in your directory):
(Note: This field is known as otherMails in Azure AD Graph API, AlternateEmailAddresses in Azure AD PowerShell v1 (MSOnline), and OtherMails in Azure AD PowerShell v2 (AzureAD). In all cases, it's an array of strings, not a single value.)
You can create more user-friendly usernames by adding and verifying a custom domain name to you Azure AD directory: https://learn.microsoft.com/en-us/azure/active-directory/active-directory-add-domain. Once you've done this, you can create users that have usernames such as user#contoso.com (assuming contoso.com is the domain you added).
At this point, it may be that user#contoso.com is also the email address of that user, but again—there is no assumption in Azure AD that this is the case.
For anyone running into issues using with this with an Office 365 developer account, make sure you go through the entire registration process. I thought I had completely setup my office 365 dev account, but I had missed a part related to setting up email.
Also if you are using your personal Microsoft account, for testing etc., be aware that it may appear like some things work the same as the full version or Office 365 dev, but they don't.

Resources