Announcing the new version of Graph API: api-version=1.5

The Azure AD Graph team is very pleased to announce the availability of the next version of Azure AD Graph API, api-version=1.5.  With this release we've opened up a new set of scenarios for developers, which we'll describe in more detail below:

  1. Authorize access to your applications based on group claims or application specific roles claims present
    in tokens. Through Graph API you can now:
    1. Configure the group membership claims issuance policy on an application
    2. Define roles specific to your application.  These roles can be chosen when assigning the application to users, groups or service principals, either programmatically or through the Azure Management Portal. When the user signs in to the application the user token will contain a roles claim with any of the application roles the user was assigned to - either directly or indirectly through group assignment.
  2. Expose your application as a web API secured by Azure AD by defining OAuth2.0 permission scopes.  These permission scopes may then be chosen by client applications that call your web API.
  3. Directory Extensions is now released for General Availability, with a new additional capability that differential query will now respond with any changes to schema extended properties too.

For full details of all the changes in api-version 1.5 (from the previous api-version=2013-11-08), please see https://msdn.microsoft.com/en-us/library/azure/dn835125.aspx.

NOTE:   In this blog we'll also provide some details on the latest application manifest updates. You should note that the operations described in 1 and 2 above are also configurable through the application manifest.

At the same time as releasing a new version of Graph API, we've also released a new Graph client library with lots of cool new capabilities.  You can check out our blog post for that here.

General information about version 1.5

In this release we also focused on improvements based on developer’s feedback. Versioning scheme has been updated to numeric major.minor format and is better aligned with versioning scheme of Office 365 REST APIs GA release.

The schema namespace of Graph API has changed from Microsoft.WindowsAzure.ActiveDirectory to Microsoft.DirectoryServices. This affects all entities and complex types exposed by Graph API. 

Additionally starting with this version, we plan to start adding new entities and properties more frequently without revisiting the service version in order to allow developers to take advantage of new features sooner.  If you are using the WCF client library, then you should make sure to set “IgnoreMissingProperties” to true.  You’ll need this anyway to support directory schema extensions. Please do let us know what you think. We are looking forward to hearing your feedback about this approach.

Application roles

You can define roles specific to your application.  Imagine you have a Dental Practice app - you might define the following roles:

  • "Dentist" role allowed to create, view and update
    patient health records
  • "Receptionist" role allowed to create and manage patient
    information (but not personal health details), and manage appointments.

These application roles can be assigned to a user or group (as well as a service principal).  Then when a user signs in to the application, the user token will contain a roles claim with any of the application roles the user was assigned to - either directly or indirectly through group assignment.  This then allows your application to make authorization decisions purely based on the roles claim.  We'll show you how to create, view, update and delete application roles, as well as assigning and removing assignments of application roles.

Adding and viewing application roles

NOTE: application roles can be created as part of application creation - however that is not shown here.  Instead we'll just how you how to add app roles to an existing application.  The following shows the addition of the 2 roles described above.

PATCH

https://graph.windows.net/contoso.com/application/02a8a087-a371-43f9-94df-cf0f654de307?api-version=1.5

HEADERS

Content-Type: application/json

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1T….

BODY:

{   "appRoles": [

{

"allowedMemberTypes": [    "User"  ],  "description": "Dentists may create and update patient's health records",  "displayName": "Dentist",  "id": "31952ade-a03c-414c-8340-2f11e9099106",  "isEnabled": true,  "value": "dentist"

 },

{

  "allowedMemberTypes": [         "User"       ],       "description": "Receptionists may manage patient  information and appointments",       "displayName": "Receptionist",       "id": "55048f57-6105-4fef-bb3a-96dcc6db90bb",       "isEnabled": true,       "value": "receptionist"

 }

  ]

}  

allowedMemberTypes describes the entities that the role may be assigned to.  User means the role can be assigned to a useror group.  Application means the role can be assigned to another application - in the form of a service principal.  This latter scenario is allows a different client application to call this application's API in a particular role.  More details can be found on the AppRole complex type description.

Viewing a role

Viewing a role is as simple as getting the application entity:

GET https://graph.windows.net/contoso.com/application/02a8a087-a371-43f9-94df-cf0f654de307?api-version=1.5

The application role is returned in the appRoles collection. 

Updating a role

The following updates the existing Dentist role to allow it to be assigned to an application, as well as changing the description..  Note that the whole appRoles collection must be sent again in the update, including the edits that you wish to make.  If you want to add a new app role then you need to add it to the existing collection.

PATCH

https://graph.windows.net/contoso.com/application/02a8a087-a371-43f9-94df-cf0f654de307?api-version=1.5

HEADERS

Content-Type: application/json

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1T….

BODY:

{   "appRoles": [

    {     

  "allowedMemberTypes": [         "User", “Application”       ],       "description": "Dentists may create, update and delete patient's health records",     "displayName": "Dentist",       "id": "31952ade-a03c-414c-8340-2f11e9099106",       "isEnabled": true,       "value": "dentist"   

     },

    {     

  "allowedMemberTypes": [         "User"       ],       "description": "Receptionists may manage patient information and appointments",       "displayName": "Receptionist",       "id": "55048f57-6105-4fef-bb3a-96dcc6db90bb",       "isEnabled": true,       "value": "receptionist"

    }

  ]

}

 

Deleting a role

Deleting a role is possible, but you'll need to be sure to update your application code to account for the fact that existing users, groups and service principals may have already been assigned this deleted role.  Your app code will still need to support this roles claim value showing up.

To delete an app role, you must first update the app role (PATCH) by setting isEnabled to false.  Once that is done, create a new JSON appRoles collection payload without the app role you want to delete, and update using PATCH. 

Viewing application role assignments

The following will list all application role assignments for a user:

GET https://graph.windows.net/contoso.com/users/jon\@contoso.com/appRoleAssignments?api-version=1.5

Similarly for a group:

GET https://graph.windows.net/contoso.com/groups/84b80893-8749-40a3-97b7-68513b600544/appRoleAssignments?api-version=1.5

Similarly for a service principal (to see the app role assignments an application has to call into a resource application):

GET https://graph.windows.net/contoso.com/servicePrincipals/af91723a-eb0a-4711-b1bb-39b7f733491e/appRoleAssignments?api-version=1.5

To view the list of all app role assignments to a resource (represented by a service principal) – this will allow you to tell which users, groups and service principals are assigned to this resource:

GET https://graph.windows.net/contoso.com/servicePrincipals/a5e465e4-397d-4913-b232-15500d76ea09/appRoleAssignedTo?api-version=1.5

Assigning application roles

The following will assign the dentist application role described earlier to a user.

POST

https://graph.windows.net/contoso.com/ users/jon@contoso.com/appRoleAssignments?api-version=1.5

HEADERS

Content-Type: application/json

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1T….

BODY:

{   "id": "31952ade-a03c-414c-8340-2f11e9099106",   "principalId":  "84b80893-8749-40a3-97b7-68513b600544",   "principalType": "User",   "resourceId":  "29c7ed43-a9a1-4b31-8a64-fc90c3ca4e73"

}

RESPONSE 201

{

   "odata.metadata":https://graph.windows.net/contoso.com/$metadata#directoryObjects/Microsoft.DirectoryServices.AppRoleAssignment/@Element,    "odata.type":"Microsoft.DirectoryServices.AppRoleAssignment",    "objectType":"AppRoleAssignment",   "objectId":"kwi4hEmHo0CXt2hRO2AFRKOaYLLQbgVIqOCz-qKlrO0",    "creationTimestamp":"2014-11-12T18:53:46.3182573Z",    "id":"31952ade-a03c-414c-8340-2f11e9099106",    "principalDisplayName":"Jon Doe",    "principalId":"84b80893-8749-40a3-97b7-68513b600544",    "principalType":"User",    "resourceDisplayName":"Dental Practice Manager",    "resourceId":"29c7ed43-a9a1-4b31-8a64-fc90c3ca4e73"

}

NOTE:   It is possible to assign a user or a group to a resource through appRoleAssignments. This is possible even if the resource does not declare any app roles. In this case you should set the “id” in the request body to a zero GUID value.

NOTE:   Currently assignment of a service principal to a resource is broken and we’ll work to fix this problem, and update this post when it's fixed.

Removing application role assignments

DELETE https://graph.windows.net/contoso.com/users/jon\@contoso.com/appRoleAssignments/kwi4hEmHo0CXt2hRO2AFRKOaYLLQbgVIqOCz-qKlrO0?api-version=1.5

 

OAuth2.0 Permission Scopes

Expose your application as a RESTful API secured by Azure AD by defining OAuth2.0 permission scopes.  These permission scopes may then be chosen by client applications that call your API using the RequiredResourceAccess complex type.

Creating OAuth2.0 Permission Scopes

NOTE: Permission scopes can be created as part of application creation - however that is not shown here.  Instead we'll just how you how to add permission scopes to an existing application. The following shows the addition of a single permission that represents the ability for the calling application to fully impersonate the signed in user without any constraint.  This permission may be granted by both users and administrators (type = User) and contains different display names and descriptions depending on whether this app is being consented to by a user, or by an admin on behalf of the school or company.

PATCH

https://graph.windows.net/contoso.com/application/02a8a087-a371-43f9-94df-cf0f654de307?api-version=1.5

HEADERS

Content-Type: application/json

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1T….

BODY:

{   "oauth2Permissions": [

    {      

  "adminConsentDescription": "Allow the application to access Web API perms on behalf of the signed-in user.",       "adminConsentDisplayName": "Access Web API perms",      "id": "dedd4bf0-e402-4f49-9762-0d32c884e6c2",   "isEnabled": true,        "type": "User",       "userConsentDescription": "Allow the application to access Web API perms on your behalf.",       "userConsentDisplayName": "Access Web API perms",       "value": "user_impersonation"

    }

  ],

}  

 

Updating OAuth2.0 Permission Scopes

This follows the same pattern as updating application roles. 

Deleting OAuth2.0 Permission Scopes

This follows the same pattern as deleting application roles. 

Granting OAuth2.0 permissions

The mechanism for this has not been updated in 1.5, although the link has been renamed from "permissions" to "oauth2PermissionGrants". 

Configuring your app to access other resources

While this is possible through the RequiredResourceAccess complex type, discovering other developer’s API appId and the oauth2Permissions or appRole unique identifiers they expose may be difficult.  For those scenarios, it’s recommended to actually configure this through UX – either in the Azure Management Portal (under the configure applications “Access to other applications” section) or through the Office
365 API tools for Visual Studio

RequiredResourceAccess can also be viewed and set through the application manifest file. 

Updates to directory roles

In Graph API 1.5, roles has been renamed to DirectoryRoles, so that we avoid any confusion with appRoles (described earlier). DirectoryRoles represent the built-in roles exposed by the directory itself, some of which are described here

By default, when a tenant is created, only the Company Administrator role is instantiated (along with an implicit User role).  In order to assign users or service principals to one of the built-in roles, that role
first has to be instantiated from a directory role template.  The set of available roles can be listed using the DirectoryRoleTemplate read-only entity. 

GET

https://graph.windows.net/contoso.com/directoryRoleTemplates?api-version=1.5

HEADERS

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1T….

RESPONSE: 201

{

"odata.metadata":https://graph.windows.net/contoso.com/$metadata#directoryObjects/Microsoft.DirectoryServices.DirectoryRoleTemplate,

"value": [{

                "odata.type": "Microsoft.DirectoryServices.DirectoryRoleTemplate",

                "objectType": "RoleTemplate",

                "objectId":  "fe930be7-5e62-47db-91af-98c3a49a38b1",

                "deletionTimestamp": null,

                "description": "User Account Administrator has access to perform common user management related tasks.",

                "displayName":  "User Account Administrator"

},

{

                "odata.type": "Microsoft.DirectoryServices.DirectoryRoleTemplate",

                "objectType": "RoleTemplate",

                "objectId": "f023fd81-a637-4b56-95fd-791ac0226033",

                "deletionTimestamp": null,

                "description": "Service Support Administrator has access to perform common support tasks.",

                "displayName": "Service Support Administrator"

},

{

}]

}

To instantiate the role from a template, use the objectId of the desired role template. So for example, if we want to instantiate the User Account Administratorrole, perform the following POST operation on DirectoryRoles, setting roleTemplateId to fe930be7-5e62-47db-91af-98c3a49a38b1: 

POST

https://graph.windows.net/contoso.com/directoryRoles?api-version=1.5

HEADERS

Content-Type: application/json

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1T….

BODY:

{   "roleTemplateId": " fe930be7-5e62-47db-91af-98c3a49a38b1"

}

RESPONSE 201

{

                "odata.metadata":"https://graph.windows.net/contoso.com/$metadata#directoryObjects/Microsoft.DirectoryServices.DirectoryRole/@Element",

                "odata.type": "Microsoft.DirectoryServices.DirectoryRole",

                "objectType": "Role",

                "objectId": "0b4f933e-bca3-4c4c-8469-7431fa4244c3",

                "deletionTimestamp": null,

                "description": null,

                "displayName": null,

                "isSystem": null,

                "roleDisabled":  null,

                "roleTemplateId": "729827e3-9c14-49f7-bb1b-9608f156bbb8"

}

Querying the DirectoryRoles will show the instantiated directory roles including the newly instantiated User Account Administrator role:

GET https://graph.windows.net/contoso.com/directoryRoles?api-version=1.5 

You can assign a user to a directory role by performing a POST operation on a specific directory roles link members as described here, where the directory role is specified by its objectId (and not its role template ID).  When an application is configured to request group membership claims, the directory roles (object id) that the user is a member of will appear in these claims. 

A little information about the Application Manifest

Through the Azure Management Portal, you are able to download, as well as upload a file representation of your application (in JSON format). No actual file is stored in the directory - the application manifest is merely a GET on the application entity, and the upload is a PATCH on the application entity. As a result, in order to find documentation on the format and properties of the application manifest, simply review the MSDN reference documentation on the application entity

The Azure Management Portal provides UX for you to update the most common properties of an application.  For more advanced scenarios, that are not exposed in the UX, you can use the application manifest, as an alternative to writing an application to call the Graph API to update your applications. Example updates that can be performed though app anifest upload include:

  1. Declare permission scopes (oauth2Permissions) exposed by your web API
  2. Declare application roles (appRoles) exposed by your app
  3. Declaring known client applications
  4. Request Azure AD issue group memberships claim for the signed in user.  NOTE:  this can be configured to additionally issues claims about the user's directory roles memberships.
  5. Allow your application to support OAuth 2.0 Implicit grant flows (for embedded JS web pages or SPA)
  6. Enable use of X509 certificates as the secret key 

The application manifest also provides a good way to track the state of your app registration, and this file representation can be checked in along with your app's source code. 

NOTE:   For the Graph API 1.5 release, the application manifest signature has changed. There is currently no versioning support, so any attempts to upload an older format application manifest (generated before the release of Graph API 1.5) will result in an error.  In this case simply re-download your app manifest from the Azure Management Portal to get the latest format. 

Directory Schema Extensions

Directory extensions is now released for General Availability.

You can use directory schema extensions to store application data in the directory without having to store the same data in your own application profile database.  For more scenarios anddetails on the entities that can be extended, possible extensions, and how to use the Graph API to manipulate extensions please see our topic on Directory Schema Extensions.

NOTE:  Any extensions you created during the preview period for this feature are supported in 1.5.

Additionally, differential query will now respond with any changes to schema extended properties too.

Feedback

We hope you like the new functionality that we've added to the graph API in version 1.5. Please let us know what you think.

 

Thanks,

The Azure AD Graph API team.