closes #92
This commit is contained in:
Hong Ooi 2021-10-13 10:51:29 +11:00 коммит произвёл GitHub
Родитель 6158983c05
Коммит 6e9ba75d82
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 89 добавлений и 4 удалений

Просмотреть файл

@ -1,5 +1,6 @@
# Microsoft365R 2.3.1.9000
- Add a vignette "Using Microsoft365R in an unattended script".
- Add a `get_path()` method for drive items, which returns the path to the item starting from the root. Needed as Graph doesn't seem to store the path in an unmangled form anywhere.
- Fix broken methods for accessing items in shared OneDrive/SharePoint folders (#89).
- Fix a bug in sending file attachments in Teams chats (#87).

Просмотреть файл

@ -46,13 +46,11 @@ get_team("My team", tenant="mytenant")
## App registration and approvals
For authentication purposes, the package is registered as an app in the 'aicatr' AAD tenant; depending on your organisation's security policy, you may have to get an admin to grant it access to your tenant. See [app_registration.md](https://github.com/Azure/Microsoft365R/blob/master/inst/app_registration.md) for details on the app, including the permissions it requires.
Microsoft365R comes with a default app registration for authenticating with AAD; depending on your organisation's security policy, you may have to get an admin to grant it access to your tenant. See [app_registration.md](https://github.com/Azure/Microsoft365R/blob/master/inst/app_registration.md) for details on the permissions that Microsoft365R requires.
### Using your own app registration
Rather than getting the Microsoft365R app approved, you can also use your own app registration for authentication. One specific scenario where this is **required** if you want to use Microsoft365R with Shiny---see the vignette "Using Microsoft365R in a Shiny app" for more on this topic, including how to configure the app registration in Azure Active Directory.
For use in a local R session, if you want to use the default authorization code flow, the app registration should have a mobile & desktop redirect URI of `https://localhost:1410` (not a web or SPA redirect). If you want to use the device code flow, the "Allow native client" setting should be enabled. Your app should also have the same default permissions as the Microsoft365R app (see above).
Rather than getting the default app registration approved, you can also create your own registration for authentication. If this is for use in a local R session, it should have a mobile & desktop redirect URI of `https://localhost:1410` (not a web or SPA redirect), and the "Allow native client" setting should be enabled. You can use the same permissions as the default app, or set your own: for example, if you know you don't need to interact with Outlook, you can omit the Mail.Send and Mail.ReadWrite permissions.
Once the app has been registered, you can pass the app ID to Microsoft365R in a couple of ways.
@ -64,6 +62,13 @@ Once the app has been registered, you can pass the app ID to Microsoft365R in a
- Alternatively, if the environment variable `CLIMICROSOFT365_AADAPPID` is set, Microsoft365R will use its value as the app ID for authenticating to the Microsoft 365 Business services (Teams, SharePoint and OneDrive for Business). This environment variable is defined by the [CLI for Microsoft365](https://pnp.github.io/cli-microsoft365/), an open source tool for managing Microsoft 365 accounts; you thus can reuse the same app ID for both the CLI and Microsoft365R.
If you want to use Microsoft365R outside a local R session, creating a custom app registration is **required**. In particular, this includes the following common scenarios:
- Using Microsoft365R inside a Shiny webapp
- Using it in an unattended (automated) script, eg in a GitHub Actions workflow or other CI/CD pipeline
See the vignettes "Using Microsoft365R in a Shiny app" and "Using Microsoft365R in an unattended script" for more on these use cases, including how to configure the app registration in Azure Active Directory.
### Using other app registrations: last-resort workarounds
The above methods are the **recommended solutions** to dealing with access restrictions on Microsoft365R. If they are not feasible, it's possible to work around these issues by piggybacking on other apps:

79
vignettes/scripted.Rmd Normal file
Просмотреть файл

@ -0,0 +1,79 @@
---
title: "Using Microsoft365R in an unattended script"
author: Hong Ooi
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Microsoft365R in an unattended script}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{utf8}
---
This vignette describes how to incorporate Microsoft365R into an automated (unattended) script, such as for a GitHub Actions workflow or other CI/CD process. This involves creating a new app registration that has application permissions, and using it to work with the Microsoft Graph API.
## App registration
The default Microsoft365R app registration only has _delegated_ permissions. This means that it requires you to authenticate with Azure Active Directory (AAD) to obtain an OAuth token, after which it will use your credentials to perform tasks. This doesn't work if you want to use the package in an automated script, ie one that is meant to run without user intervention.
In this situation, you must create a new app registration in AAD that has _application_ permissions. This means that, rather than using the credentials of a logged-in user, Microsoft365R has its own, custom set of permissions that determine what it can do.
The app registration for an unattended script looks slightly different to that for a user-facing application.
- There is no redirect URI, since we don't need a user to authenticate in a browser.
- You must set the **client secret**, which is like a password that serves to verify to AAD the identity of the workflow calling the script. Alternatively, you can use a certificate instead of a secret; this is more secure but also more complicated to setup and use.
- In nearly all cases, the **intended audience** of your app registration should be only members of your AAD tenant.
- Ensure that you give your app **application permissions** instead of delegated permissions. Refer to the complete [list of Graph permissions](https://docs.microsoft.com/en-us/graph/permissions-reference?context=graph%2Fapi%2Fbeta&view=graph-rest-beta) to determine which ones you need.
The following pages at the AAD documentation will be helpful:
- [A step-by-step guide](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) to registering an app in the Azure portal.
- [How to set permissions for an app](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis).
- [Authentication and authorization basics for Microsoft Graph](https://docs.microsoft.com/en-us/graph/auth/auth-concepts#microsoft-graph-permissions).
### Application permissions and security
It's important to note that application permissions are _much more powerful_ than delegated permissions. From the "Authentication and authorization basics" link above:
> For application permissions, the effective permissions of your app will be the full level of privileges implied by the permission. For example, an app that has the User.ReadWrite.All application permission can update the profile of every user in the organization.
For this reason, you should only give your app registration the minimum permissions it needs to get the job done. In particular, avoid giving your app read/write permissions if it only needs to read data.
## Sample code skeleton
Here is a simple script that retrieves a given user's OneDrive and lists the contents of the root directory. We cannot use `get_personal/business_onedrive`, because these client functions assume that a user is logged in. Instead, we call the underlying R6 methods directly.
For this script, the application permissions needed are:
- Get a user's details: User.Read
- Read from OneDrive: Files.Read
```r
library(AzureGraph)
library(Microsoft365R)
tenant <- "your-tenant-here"
# the application/client ID of the app registration you created in AAD
# - not to be confused with the 'object ID' or 'service principal ID'
app <- "your-app-id-here"
# retrieve the client secret (password) from an environment variable
pwd <- Sys.getenv("EXAMPLE_MS365R_CLIENT_SECRET")
# retrieve the user whose OneDrive we want to access
# - this should be their 'userPrincipalName', which is of the form 'name@tenant.com'
# - note this may be different to their regular email address
user <- Sys.getenv("EXAMPLE_MS365R_TARGET_USER")
# create a Microsoft Graph login
gr <- create_graph_login(tenant, app, password=pwd, auth_type="client_credentials")
drv <- gr$get_user(user)$get_drive()
drv$list_files()
```