Azure Active Directory B2C: How to query MS Graph to get a user's alternative security ID? - azure-active-directory

B2C uses an alternative security ID to uniquely identify users from social accounts. We have a problem where a user enters credentials for a user, but somehow B2C authenticates the user as someone else. I suspect the IDP is returning bad claims data or the alternative security IDs are the same. How do I view the alternative security ID of a user in Active Directory?
I tried the following MS Graph query trying all the attributes I can think of (including the ones listed in this article), but graph doesn't return data for these attributes.
https://graph.microsoft.com/v1.0/users/<userId>?$select=id,alternativeSecurityId,alternativeSecurityIds,extension_<b2cExtensionAppId>_alternativeSecurityId,extension_<b2cExtensionAppId>_alternativeSecurityIds
Thanks in advance!

AlternativeSecurityId for a B2C user is found in the Identities collection via MS Graph API.
The AlternativeSecurityId claim used in the B2C policy maps to the Identities: issuerAssignedId value for the corresponding issuer.
Eg, for issuerAssignedId: 123 (id from google token) from issuer: google.com
"identities": [
{
"signInType": "federated",
"issuer": "google.com",
"issuerAssignedId": "123"
}
],
You can return the identities collection by calling the /users endpoint of MS Graph API. https://learn.microsoft.com/en-us/graph/api/user-list?view=graph-rest-1.0&tabs=http

Related

Create users on B2C tenant : triggered by user creation on AzureAD

Use case : A user is created in Azure AD. As soon as the user is created, another account should be created for the user in B2C tenant (as a federated user).
Question : What is the best approach to achieve the above?
There is no AD trigger when a user is added or changed currently. The similar issue provides a workaround.
The alternative way should be make sure to create an item in a
sharepoint list when you add/delete a user in Azure AD, and then you
create a flow to trigger when an item is created/deleted is sharepoint
list.
Then you could create user to Azure AD B2C tenant with Microsoft Graph API.
POST https://graph.microsoft.com/v1.0/users
Content-type: application/json
{
"accountEnabled": true,
"displayName": "Adele Vance",
"mailNickname": "AdeleV",
"userPrincipalName": "AdeleV#contoso.onmicrosoft.com",
"passwordProfile" : {
"forceChangePasswordNextSignIn": true,
"password": "xWwvJ]6NMw+bWH-d"
}
}

How to solve "NoPermissionsInAccessToken" returned by Microsoft Graph when reading calendar or sending mail

Within our department we have a Classic ASP website that has been using our corporate Google accounts for authentication and to insert events into our Google Calendars. The organisation has just switched from Google to Office 365 and I'm trying to switch the code to use Outlook instead - with no success.
I can use the access token to GET https://graph.microsoft.com/v1.0/me and see the basic profile, but if I try to read calendar events or send an e-mail I see the message:
"error": {
"code": "NoPermissionsInAccessToken",
"message": "The token contains no permissions, or permissions can not be understood."
I created an Azure account with my personal Microsoft account and added an application. I added my colleagues and my corporate account as guest users. I set the permissions required and did the admin consent thing:
I then followed the steps on this page.
I first visit https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize, including the following query items:
client_id={client id}
response_type=code
redirect_uri={our URL}
response_mode=query
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={number}
This returns a "code", which I send to https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/token, including:
grant_type=authorization_code
client_secret={client secret}
client_id={client id}
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={same number as above}
redirect_uri={same URL as above}
code={code returned from /authorize}
This returns the id, access and refresh tokens. If I decode the access token using https://jwt.ms/, it seems to contain the appropriate audience and scope:
"aud": "https://graph.microsoft.com"
"scp": "Calendars.ReadWrite email Mail.Send openid profile User.Read"
...although I notice that there is no "roles" entry, which I see in some of the documentation. Is that an issue?
I then send the access token to https://graph.microsoft.com/v1.0/me with the following headers:
"Authorization", "Bearer {access token}"
"Host", "graph.microsoft.com"
"Content-Type", "application/json"
"Prefer", "outlook.timezone Europe/London"
That will return my e-mail address, etc., but if I change the URL to anything else, such as /me/photo/$value, /me/calendar/events, or try to send an e-mail I'm told that there are no permissions in the token.
I see that there are other similar questions, but they are mostly for the client_credentials flow (I'm not sure that makes any difference), and none of the answers has helped me resolve my problem.
Can someone please let me know if I've obviously missed anything - or I'm going about this in the wrong way to access Graph data on the client side? It seemed so straightforward with Google, but I'm finding the Microsoft documentation and examples a bit less detailed.
Adding guest users is meaningless.
What you have done is Admin consent for the Azure AD with your personal Microsoft account.
What you actually need to do is Admin consent for the target Azure AD/ O365 tenant.
Construct a consent link as following:
https://login.windows.net/{tenant ID of the target Azure AD}/oauth2/authorize?response_type=id_token&client_id={client ID}&redirect_uri={reply url}&response_mode=form_post&nonce=a4014117-28aa-47ec-abfb-f377be1d3cf5&resource=https://graph.microsoft.com&prompt=admin_consent
Access it in a browser and log in with an admin account of target Azure AD.
Another issue is that you are using Get access on behalf of a user. So you have to assign Delegated permissions rather than Application permissions in the Azure AD app.

Azure AD & Graph API Permission

I have a variety of graph permissions assigned to different web apps in Azure. Is there any way in which I can map these graph permissions back to Azure AD roles and identify which role is the permission assigned to? I need this to implement access control based on the signed-in user
Graph permissions are granted for Azure AD app. Azure AD role is to manage Azure AD rather than API permission. There is no mapping between them.
What you are looking for is appRole.
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"displayName": "Writer",
"id": "d1c2ade8-98f8-45fd-aa4a-6d06b947c66f",
"isEnabled": true,
"description": "Writers Have the ability to create tasks.",
"value": "{the custom role name}"
}
]
A sample for your reference: Authorization in a web app using Azure AD application roles & role claims.
Update
You need to add the needed Graph permissions in Azure AD APP and then control the permissions in your code.
We assume you have assigned a custom role in an Azure AD app and added a user to this role.
When a user signs in, a token which includes the role claim will be returned.
You can judge the user's role in the code. If it matches a custom appRole, he is allowed to perform an operation, such as user-invite-all . If the user does not match any of the appRoles, he does not have permission to perform any operations.
[HttpPost]
[Authorize(Roles = "Admin, Writer, Approver")]
public ActionResult TaskSubmit(FormCollection formCollection)
{
if (User.IsInRole("Admin") || User.IsInRole("Writer"))
//do something such as inviting others.
{
Please dig deeper into the sample code I shared above.
PS: Note that I have modified the value in "appRoles" in my previous answer.

MDM (not Intune) cannot report compliance status (to Azure AD) of a device currenctly being managed

I have succesfully enrolled a Device (Windows 10 Pro Version 1803) to our own MDM by authenticating an Azure AD user. Next I have to tell Azure AD that the device is managed by our MDM and that is where the problem happens.
The patch that I do is the same like in the documentation https://learn.microsoft.com/en-us/windows/client-management/mdm/azure-active-directory-integration-with-mdm#report-device-compliance-to-azure-ad
The error I got is Resource 'xyz' does not exist or one of its queried reference-property objects are not present.
What I have done so far is:
On Azure AD Portal I added an MDM OnPremise App, set its Terms Of Use URL, Discovery URL, generate a secret. Also configured MDM User scope to Some and selected a group where my users are member of.
On Required persimision I verified that "Read and write devices" under "Application Permissions" is checked.
The user authenticates (using Azure AD crendentials), accepts Terms of Use (of the MDM) and voilá all fine. That is done on the device under Settings => Accounts => Access work or school => + Connect.
During the enrollment, I parse the Bearer Token and extract the Device ID (e.g. xyz), which is the same as the one on the Azure AD portal once the device succesfully managed.
To report compliance status I do a patch like this
PATCH https://graph.windows.net/mytenant.onmicrosoft.com/devices/xyz?api-version=1.0 HTTP/1.1
Authorization: Bearer eyJ0eXAiO………
Accept: application/json
Content-Type: application/json
{ "isManaged":true,
"isCompliant":true
}
But I got the error described above.
I have tested as well different Device Ids such as
the one Windows 10 shows on Settigns => System => About.
Or the one that is present on the element ContextItem attribute DeviceID on the Request Security Token request during enrollment.
The bearer token I use on the patch above is retrieved from microsoft graph when the registered MDM app (using its credentials such as appid, secret, etc) authenticates it self to Azure AD.
Whould you please help me to find the source of this error, or maybe give me some hints in order to solve this. I'd apreciate it a lot.
Thanks in advance.
The deviceId of a Device object in Azure AD is often confused with the object's objectId attribute. (The latter is known as objectId in Azure AD Graph, and as id in Microsoft Graph. In both cases, deviceId is a different property.)
In a GET request for a single Device object with Azure AD Graph:
GET https://graph.windows.net/{tenant-id}/devices/{object-id}
The field identified by {object-id} is not the deviceId attribute of the Device object, it's the objectId attribute.
If you don't already have the Device object's objectId value, but you do have the deviceId, you can use either Azure AD Graph or Microsoft Graph to do the appropriate lookup. With Azure AD Graph:
GET https://graph.windows.net/{tenant-id}/devices?$filter=deviceId eq '{device-id}'
With Microsoft Graph, you would use:
GET https://graph.microsoft.com/v1.0/devices?$filter=deviceId eq '{device-id}'

How to get Azure tenant name from graph.microsoft.com?

I need to discover user's tenant name, since the service endpoint, resourceId that I'll be using an Azure service that requires me to specify the tenant name:
service endpoint: https://[tenantnamme].api.crm.dynamics.com/...
resource Id: https://[tenantname].crm.dynamics.com
I was hoping Unified Microsoft Graph API can discover this for me. I looked at the documentation, the closest I can see is to use
graph.microsoft.com/v1.0/organization
which will give me back:
verifiedDomains : [
....
"name" : "contoso.onmicrosoft.com"
]
But, I'm not sure if this is the right approach. What if an org has multiple verified domains? Does verified domain name is the same as tenant name?
Update: This is my real scenario. I have a web app that allows user to authenticate to Azure AD via OAuth2. I have no problem obtaining refresh token and access token from OAuth interactions. However, in other to use other service, it requires [azure-ad-tenant-name] in their service end point. That's my question coming from.
I believe that you're on the right track with the graph.microsoft.com/v1.0/organization endpoint. You should be able to find the tenant name in the verifiedDomains list. The entry that should contain domain with the tenant name is the initial domain:
{
...
"isInitial": true,
"name": "contoso.onmicrosoft.com",
...
}
Same. When you create a AD, you will obtain a domain name and a tenant id without tenant name, they are both the unique identifier of a AD. Use Get-AzureRmTenant to get all tenantid and domains in your subscription.

Resources