Microsoft Graph is a comprehensive framework for accessing data in various online Microsoft services, including Azure Active Directory (AAD), Office 365, OneDrive, Teams, and more. AzureGraph is a simple R6-based interface to the Graph REST API, and is the companion package to AzureRMR and AzureAuth.
Currently, AzureGraph aims to provide an R interface only to the AAD part, with a view to supporting R interoperability with Azure: registered apps and service principals, users and groups. However, it can be extended to support other services; for more information, see the “Extending AzureGraph” vignette.
The first time you authenticate with a given Azure Active Directory
tenant, you call create_graph_login()
and supply your
credentials. AzureGraph will prompt you for permission to create a
special data directory in which to cache the obtained authentication
token and AD Graph login. Once this information is saved on your
machine, it can be retrieved in subsequent R sessions with
get_graph_login()
. Your credentials will be automatically
refreshed so you don’t have to reauthenticate.
library(AzureGraph)
# authenticate with AAD
# - on first login, call create_graph_login()
# - on subsequent logins, call get_graph_login()
gr <- create_graph_login()
See the “Authentication basics” vignette for more details on how to authenticate with AzureGraph.
The basic classes for interacting with user accounts and groups are
az_user
and az_group
. To instantiate these,
call the get_user
and get_group
methods of the
login client object. You can also list the users and groups with the
list_users
and list_groups
methods.
# account of the logged-in user (if you authenticated via the default method)
me <- gr$get_user()
# alternative: supply a GUID, name or email address
me2 <- gr$get_user(email="hongooi@microsoft.com")
# lists of users and groups (may be large!)
gr$list_users()
gr$list_groups()
# IDs of my groups
head(me$list_group_memberships())
#> [1] "98326d14-365a-4257-b0f1-5c3ce3104f75" "b21e5600-8ac5-407b-8774-396168150210"
#> [3] "be42ef66-5c13-48cb-be5c-21e563e333ed" "dd58be5a-1eac-47bd-ab78-08a452a08ea0"
#> [5] "4c2bfcfe-5012-4136-ab33-f10389f2075c" "a45fbdbe-c365-4478-9366-f6f517027a22"
# a specific group
(grp <- gr$get_group("82d27e38-026b-4e5d-ba1a-a0f5a21a2e85"))
#> <Graph group 'AIlyCATs'>
#> directory id: 82d27e38-026b-4e5d-ba1a-a0f5a21a2e85
#> description: ADS AP on Microsoft Teams.
#> - Instant communication.
#> - Share files/links/codes/...
#> - Have fun. :)
The actual properties of an object are stored as a list in the
properties
field:
# properties of a user account
names(me$properties)
#> [1] "@odata.context" "id" "deletedDateTime"
#> [4] "accountEnabled" "ageGroup" "businessPhones"
#> [7] "city" "createdDateTime" "companyName"
#> [10] "consentProvidedForMinor" "country" "department"
#> [13] "displayName" "employeeId" "faxNumber"
#> ...
me$properties$companyName
#> [1] "MICROSOFT PTY LIMITED"
# properties of a group
names(grp$properties)
#> [1] "@odata.context" "id" "deletedDateTime"
#> [4] "classification" "createdDateTime" "description"
#> [7] "displayName" "expirationDateTime" "groupTypes"
#> [10] "mail" "mailEnabled" "mailNickname"
#> [13] "membershipRule" "membershipRuleProcessingState" "onPremisesLastSyncDateTime"
#> ...
You can apply a filter to the list_users
and
list_groups
methods, to cut down on the number of results.
The filter should be a supported OData
expression. For example, this will filter the list of users down to
your own account:
# get my own name
my_name <- me$properties$displayName
gr$list_users(filter=sprintf("displayName eq '%s'", my_name))
You can also view any directory objects that you own and/or created,
via the list_owned_objects
and
list_registered_objects
methods of the user object. These
accept a type
argument to filter the list of objects by the
specified type(s).
me$list_owned_objects(type="application")
#> [[1]]
#> <Graph registered app 'AzureRapp'>
#> app id: 5af7bc65-8834-4ee6-90df-e7271a12cc62
#> directory id: 132ce21b-ebb9-4e75-aa04-ad9155bb921f
#> domain: microsoft.onmicrosoft.com
me$list_owned_objects(type="group")
#> [[1]]
#> <Graph group 'AIlyCATs'>
#> directory id: 82d27e38-026b-4e5d-ba1a-a0f5a21a2e85
#> description: ADS AP on Microsoft Teams.
#> - Instant communication.
#> - Share files/links/codes/...
#> - Have fun. :)
#>
#> [[2]]
#> <Graph group 'ANZ Data Science and AI V-Team'>
#> directory id: 4e237eed-5f9b-4abd-830b-9322cb472b66
#> description: ANZ Data Science V-Team
#>
#> ...
To get the details for a registered app, use the get_app
or create_app
methods of the login client object. These
return an object of class az_app
. The first method
retrieves an existing app, while the second creates a new app.
# an existing app
gr$get_app("5af7bc65-8834-4ee6-90df-e7271a12cc62")
#> <Graph registered app 'AzureRapp'>
#> app id: 5af7bc65-8834-4ee6-90df-e7271a12cc62
#> directory id: 132ce21b-ebb9-4e75-aa04-ad9155bb921f
#> domain: microsoft.onmicrosoft.com
# create a new app
(appnew <- gr$create_app("AzureRnewapp"))
#> <Graph registered app 'AzureRnewapp'>
#> app id: 1751d755-71b1-40e7-9f81-526d636c1029
#> directory id: be11df41-d9f1-45a0-b460-58a30daaf8a9
#> domain: microsoft.onmicrosoft.com
By default, creating a new app will also generate a strong password
with a duration of two years, and create a corresponding service
principal in your AAD tenant. You can retrieve this with the
get_service_principal
method, which returns an object of
class az_service_principal
.
appnew$get_service_principal()
#> <Graph service principal 'AzureRnewapp'>
#> app id: 1751d755-71b1-40e7-9f81-526d636c1029
#> directory id: 7dcc9602-2325-4912-a32e-03e262ffd240
#> app tenant: 72f988bf-86f1-41af-91ab-2d7cd011db47
# or directly from the login client (supply the app ID in this case)
gr$get_service_principal("1751d755-71b1-40e7-9f81-526d636c1029")
#> <Graph service principal 'AzureRnewapp'>
#> app id: 1751d755-71b1-40e7-9f81-526d636c1029
#> directory id: 7dcc9602-2325-4912-a32e-03e262ffd240
#> app tenant: 72f988bf-86f1-41af-91ab-2d7cd011db47
To update an app, call its update
method. For example,
use this to set a redirect URL or change its permissions. Consult the
Microsoft Graph documentation for what properties you can update.
#' # set a public redirect URL
newapp$update(publicClient=list(redirectUris=I("http://localhost:1410")))
One app property you cannot change with update
is its password. As a security measure, app passwords are auto-generated
on the server, rather than being specified manually. To manage an app’s
password, call the add_password
and
remove_password
methods.
#' # add a password
newapp$add_password()
#' remove a password
pwd_id <- newapp$properties$passwordCredentials[[1]]$keyId
newapp$remove_password(pwd_id)
Similarly, to manage an app’s certificate for authentication, call
the add_certificate
and remove_certificate
methods.
The classes described above inherit from the az_object
class, which represents an arbitrary object in Azure Active Directory.
This has the following methods:
list_group_memberships()
: Return the IDs of all groups
this object is a member of.list_object_memberships()
: Return the IDs of all
groups, administrative units and directory roles this object is a member
of.In turn, the az_object
class inherits from
ms_object
, which is a base class to represent any object
(not just an AAD object) in Microsoft Graph. This has the following
methods:
delete(confirm=TRUE)
: Delete an object. By default, ask
for confirmation first.update(...)
: Update the object information in Azure
Active Directory (mentioned above when updating an app).do_operation(...)
: Carry out an arbitrary operation on
the object.sync_fields()
: Synchronise the R object with the data
in Azure Active Directory.get_list_pager()
: Returns a pager object for iterating
through the items in a list of results. See the “Batching and paging”
vignette for more information on this topic.In particular, the do_operation
method allows you to
call the Graph REST endpoint directly. This means that even if
AzureGraph doesn’t support the operation you want to perform, you can do
it manually. For example, if you want to retrieve information on your
OneDrive:
See the following links on Microsoft Docs for more information.