I have a requirement, where I needed to fetch the tenantDirectoryId for a given subscription.
I could find a rest get api https://management.azure.com/subscriptions/[subscription]/versions...
The error response to this gave the tenant directory.
Is there any better way to fetch directory for a subscriptionId.
As of now (06/07/2018), an easy approach would be running az account show in the Azure Cloud Shell (requires a Storage Account) in the Azure Portal.
--- Command ---
az account show
--- Command Output ---
{
"environmentName": "AzureCloud",
"id": "{Subscription Id (GUID)}",
"isDefault": true,
"name": "{Subscription Name}",
"state": "Enabled",
"tenantId": "{Tenant Id (GUID)}",
"user": {
"cloudShellID": true,
"name": "{User email}",
"type": "user"
}
}
See this doc for more details on Azure Cloud Shell: https://learn.microsoft.com/en-us/azure/cloud-shell/overview
We have recently had the same problem we wanted to fix. After speaking to Microsoft there is no supported way to do this through the Graph API when accessing as an application using the client_credentialflow.
An approach we have taken to get the tenant id is to call the OAuth2 metadata document endpoint for your tenant
https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration
By calling this you’ll see your token endpoint as well as other useful information listed which you can utilise to log in. Or you can grab the tenant id using string stripping.
Related
Using Azure AD Premium, Enterprise App & SCIM 2.0 Provisioning Scope - Only assigned Users & Groups
I'm trying to work through the use case below:
SCIM provisioning of users that are assigned to a given AD Group
When a user is added (provisioned) to a group it correctly fires off a PATCH /Groups/{Id} to add member of the group
When a user is removed (deprovisioned) from the group it does not correctly fires a PATCH /Groups/{Id} to remove member of the group
What am I'm doing wrong?
In addition, I wonder which call azure active directory executes to get to know who is currently member of a given group. (I've noticed that every call AAD makes to my SCIM/group service implementation has the excludedAttributes=members as query parameter)
Any suggestions appreciated.
From what I saw, Azure SCIM sends this request to groups endpoint:
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [
{
"op": "Remove",
"path": "members",
"value": [
{
"value": "49a5f81e-9f63-4f5e-b3e8-41db044c1af9"
}
]
}
]
}
I use ngrok during the development to see an analyse requests from Azure SCIM integration.
I have an Azure AD app and I am trying to add custom claims to a JWT. I'm using the claims mapping feature in Azure for my specific app, and updated the app manifest in the Azure Portal to include the optional claims. However, when I log in and view the decoded access token, the claim is not present in the token. I haven't found much documentation relating to using extension attributes as claims, but from what I've found it should follow the same patterns, but it is not working as expected.
How do I add a custom claim, sourced from a custom property in the user object in AD, to a JWT when the user logs in?
Thanks in advance!
Steps to re-create
Use the Azure AD Graph API to register a directory extension
Request:
POST https://graph.windows.net/mytenant.onmicrosoft.com/applications/<application-object-id>/extensionProperties?api-version=1.5
Body:
{
"name": "customUserRoles",
"dataType": "String",
"targetObjects": ["User"]
}
Write a value to the extension for a specific AD user
Request:
PATCH https://graph.windows.net/mytenant.onmicrosoft.com/users/user123#mytenant.onmicrosoft.com?api-version=1.5
Body:
{
"extension_<appId>_customUserRoles": "My Custom Role 1, Another Role 2"
}
In PowerShell, I installed the Azure AD module: Install-Module -Name AzureADPreview
Create an Azure AD policy
New-AzureADPolicy -Definition #('{"ClaimsMappingPolicy":{"Version": 1, "IncludeBasicClaimSet": "true", "
ClaimsSchema": [ { "Source": "user", "ID": "extension_<appId>_customUserRoles", "JwtClaimType": "customUserRoles" } ] } }') -DisplayName "customUserRoles" -Type "ClaimsMappingPolicy"
Add the policy to the service principal
Add-AzureADServicePrincipalPolicy -Id <service-principla-id> -RefObjectId <azure-ad-policy-id>
In the Azure Portal, navigate to Azure AD -> App Registrations -> My App -> Manifest
Update the following properties
{
...
"acceptMappedClaims: true,
"optionalClaims": {
"idToken": [
{
"name": "extension_<appId>_customUserRoles",
"source": "user",
"essential": false,
}
],
"accessToken": [
{
"name": "extension_<appId>_customUserRoles",
"source": "user",
"essential": false,
}
],
"samlToken": []
}
}
Save the file
Navigate to https://login.microsoftonline.com/mytenant.onmicrosoft.com/oauth2/authorize?client_id=<appId>&response_type=token&resource=https://mytenant.sharepoint.com and login with Azure AD user account user123#mytenant.onmicrosoft.com
In the URL, copy the value of the access_token parameter
Navigate to https://jwt.ms and paste the access token in the text area
In the decoded token section, the custom claim customUserRoles is not present
My expectation is I should see a new claim called customUserRoles or extn.customUserRoles in the decoded token.
What steps am I missing? I haven't gotten any errors throughout this process, but it doesn't appear to be working as the documentation suggests.
Reference Material
I have read through Microsoft's documentation on these topics:
Optional Claims: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims
Claims Mapping: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-claims-mapping
I have also read through various forum posts and blog articles relating to this:
https://devonblog.com/cloud/azure-ad-adding-employeeid-claims-in-azure-ad-jwt-token/
http://www.redbaronofazure.com/?p=7566
https://social.msdn.microsoft.com/Forums/en-US/3e5114b6-24d6-4c60-b72b-b4c90baeecac/access-token-missing-optional-claims-that-are-schema-extensions-implicit-grant-flow
https://social.msdn.microsoft.com/Forums/en-US/dbeeed63-8d3f-4c27-b416-431f9fe6c729/providing-directory-extension-optional-claims-and-returning-value-within-token?forum=WindowsAzureAD
Based on this official doc :
Access tokens are always generated using the manifest of the resource,
not the client. So in the request
...scope=https://graph.microsoft.com/user.read... the resource is
Graph. Thus, the access token is created using the Graph manifest, not
the client's manifest. Changing the manifest for your application will
never cause tokens for Graph to look different. In order to validate
that your accessToken changes are in effect, request a token for your
application, not another app.
And based on your requirement , it is impossible if you want to make some change on an access token which resource is sharepoint online which is a multi-tenant app created and managed by MSFT.
For this doc , I also did some research for you . And the same , you should have control of the service side app so that you can make that happen.
This is my policy role assignment command :
$nsp = New-AzureADPolicy -Definition #('{"ClaimsMappingPolicy":{"Version":1,"IncludeBasicClaimSet":"true", "ClaimsSchema": [{"Source":"user","ID":"mailnickname","JwtClaimType":"testclaim"}]}}') -DisplayName "StanCustomCliamDemo_surname" -Type "ClaimsMappingPolicy"
Add-AzureADServicePrincipalPolicy -RefObjectId $nsp.Id -Id '<obj id of service side app>'
Token result :
What's more , pls note that extension_<appId>_customUserRoles is not a valid user source ID . For all valid user source ID , pls refer to here .
Hope it helps .
i wanted to add an extended property in Azure Ad which will be accessible across groups in AD.Got this
POST https://graph.windows.net/contoso.com/applications//extensionProperties?api-version=1.21-preview { “name”: “skypeId”, “dataType”: “String”, “targetObjects”: [“User”] }
Wanted to understand 2 things which the document is not clear to me on:-
1.if the "targetObjects" is specified as user will the extended property appear across groups as well as users in an application
2.can this be done directly via azure portal without using the https://graphexplorer.cloudapp.net/ as mentioned in the document
https://msdn.microsoft.com/library/azure/ad/graph/howto/azure-ad-graph-api-directory-schema-extensions#RegisterAnExtension
Does anybody have an idea on this?
if the "targetObjects" is specified as user will the extended property
appear across groups as well as users in an application
You set the "targetObjects" as the user, that means this extended property will be added in the user's attributes and also can appear across groups as well as users in this application.
can this be done directly via the Azure portal
For now, you cannot do this via the Azure portal. You could do this by using Azure AD Graph API(you tried) or Microsoft Graph API, or you can also use AAD PowerShell.
If you persist in doing this via the portal, the B2C portal is suggested for you. You could manually define a custom attribute for the user. For the details, you could read this doc.
Using Microsoft Graph API:
POST https://graph.microsoft.com/v1.0/schemaExtensions
Content-type: application/json
{
"id":"graphlearn_courses",
"description": "Graph Learn training courses extensions",
"targetTypes": [
"Group"
],
"properties": [
{
"name": "courseId",
"type": "Integer"
},
{
"name": "courseName",
"type": "String"
},
{
"name": "courseType",
"type": "String"
}
]
}
For the details, you could read here.
Using AAD PowerShell:
Set-AzureADUserExtension
-ObjectId <String>
-ExtensionName <String>
-ExtensionValue <String>
[<CommonParameters>]
For the details, you could refer to here.
I am trying to add required permissions to an Azure AD application. I already know how to replicate information from a downloaded manifest through a PATCH REST call, e.g.
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "7b9103a5-4610-446b-9670-80643382c1fa",
"type": "Scope"
},
{
"id": "5df07973-7d5d-46ed-9847-1271055cbd51",
"type": "Scope"
}
]
}
]
As explained by Christer Ljung on his blog http://www.redbaronofazure.com/?page_id=181.
But the mystery remains how I can "convert" human-readable scopes such as Mail.Read to these obscure guids. I have read the following blog of Sahil Malik's at http://blah.winsmarts.com/2015-1-Programmatically_register_native_apps_in_Azure_AD_or_Office_365.aspx that explains how to get a list of available guids for a particular ServicePrincipal. E.g. through an http get to https://graph.windows.net/<tenant-id>/servicePrincipals()?api-version=1.6&$filter=appId%20eq%20'00000002-0000-0ff1-ce00-000000000000'> (Exchange) but when I try to get the list of available scopes of ServicePrincipal 00000003-0000-0000-c000-000000000000 (I believe the one for Graph API) the return value is just empty.
Interestingly, with Fiddler I was able to capture an http post request which contains all the guids when adding the permissions through Azure Portal.
Anyone any clue how I can do this programmatically?
After investigation, I discover a way to get permission guid using azure-cli. Share here in case anyone is finding this:
get all permisson and their GUID of a certain service principal by display-name, app-id or object-id. (Note that display-name is not unique and can maps multiple service principal)
$ az ad sp list --filter "displayName eq 'Microsoft Graph'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
$ az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table | head
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
Run the below command to get full information of certain service principal including its oauth2Permissions and servicePrincipalNames, etc.
az ad sp show --id 00000003-0000-0000-c000-000000000000 >microsoft_graph_permission_list.json
# microsoft_graph_permission_list.json
{
...
"appDisplayName": "Microsoft Graph",
"appId": "00000003-0000-0000-c000-000000000000",
"objectId": "b19d498e-6687-4156-869a-2e8a95a9d659",
"servicePrincipalNames": [
"https://dod-graph.microsoft.us",
"https://graph.microsoft.com/",
"https://graph.microsoft.us",
"00000003-0000-0000-c000-000000000000/ags.windows.net",
"00000003-0000-0000-c000-000000000000",
"https://canary.graph.microsoft.com",
"https://graph.microsoft.com",
"https://ags.windows.net"
],
"appRoles": [...],
"oauth2Permissions": [
{
"adminConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read and write all users' full profiles",
"id": "204e0828-b5ca-4ad8-b9f3-f32a958e7cc4",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read and write all users' full profiles",
"value": "User.ReadWrite.All"
},
{
"adminConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read all users' full profiles",
"id": "a154be20-db9c-4678-8ab7-66f6cc099a59",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read all users' full profiles",
"value": "User.Read.All"
},
...
]
...
}
Few things to say about this topic.
First, it is important to note that all of the OAuth2Permission Scopes are registered on the main Application Object in the developer's tenant. Thus, in general, you would not have access to that information, since it would be in a tenant where you are not a user. So as an external developer, these permission scopes are not discoverable via our APIs.
Second, you are able to see that the Azure Portal has access to this information because it has elevated access to query the OAuth2Permissions for all resources in all tenants. This is how our UX is able to populate all the permissions for all the various external and internal resources that you want to use in your tenant. The portal will first check which service principals are in your tenant (service principals get provisioned most commonly once you consent to use the application), then it will look up the Application Object that corresponds to that service principal, and find all the permission scopes. This behavior will hopefully allow you to only see the resource applications which are relevant to you, rather than populating your screen with all possible resources.
Finally, moving forward we are looking to take a step back from having to statically register permissions that clients require to call resource applications. Instead we will be pushing a new Incremental and Dynamic Consent framework. You will note that here that we are taking a dependency on the scope names, rather than the ObjectID GUIDs of those permissions as we did in the past. But still, I agree with you in general that the discoverability of the scopes that resources expose is very heavily dependent their own public documentation. I imagine in the future there might be an endpoint which exposes all the scopes available on a particular resource, but I know of no such work to do this in the near future.
Let me know if this helps!
I want to know if there is a way to retrieve the registered domain(s) for a tenant through REST API for Sharepoint/Office365.
Consider this scenario;
I have a tenant named abc.pqr and url for the "my" site(OneDrive) is abc-my.sharepoint.com.
Now when I create a user for this tenant, the UI panel gives the option to select a domain for this account. Available options are;
1) #abc.pqr
2) #abc.onmicrosoft.com
Now, the problem is, if I have a user of this sort >>> testUser#abc.onmicrosoft.com, how do I findout the registered domain for this tenant? Which in my case is abc.pqr.
Is there a way to find this through REST API?
Sounds like what you want to know is the list of verified domains in your Azure Active Directory tenant. (Azure AD is the directory service behind Office 365 and other Microsoft online services.)
The Azure AD Graph API—AAD's REST API—can provide this for you. In your case, the GET request you would want to make is:
https://graph.windows.net/abc.onmicrosoft.com/tenantDetails
Note: you can use either the tenant ID or any verified domain of the tenant instead of abc.onmicrosoft.com. The tenant ID can be obtained from the tid claim in the access token.
The JSON response will include something like this:
"verifiedDomains": [
{
"capabilities": "None",
"default": true,
"id": "0007ABE0983098",
"initial": false,
"name": "abc.pqr",
"type": "Managed"
},
{
"capabilities": "Email, OfficeCommunicationsOnline",
"default": false,
"id": "0007ABE0983098",
"initial": true,
"name": "abc.onmicrosoft.com",
"type": "Managed"
}
]
(There's a useful Quickstart for the Azure AD Graph API that shows how to start playing around with AAD Graph API, and the GraphExplorer.)
If you're using .NET, there is a full sample at https://github.com/AzureADSamples/WebApp-GraphAPI-DotNet. (More samples for other languages and platforms at https://github.com/AzureADSamples.)