Common authentication scenarios

Hong Ooi

The interaction between app registration configuration and requesting a token can be confusing. This vignette outlines some common authentication scenarios that R users might encounter. For each scenario, we briefly describe the necessary settings for your app registration in Azure, and how to request a token using AzureAuth. The Azure Active Directory documentation is the authoritative reference.

Interactive authentication on a local machine

This is the simplest scenario: you’re using R on your local desktop or laptop, and you want to authenticate to Azure with your user credentials.

The authentication flow to use in this case is authorization_code. This requires that you have a browser installed on your machine, and it can be called from within R (as is usually the case). You’ll also need to have the httpuv package: this will be installed if you’re a Shiny developer, but otherwise you might have to install it manually.

The code to run in your R session is

library(AzureAuth)

# for an AADv1 token
tok <- get_azure_token("https://resource", tenant="yourtenant", app="yourappid")

# for an AADv2 token
tok <- get_azure_token("https://resource/scope", tenant="yourtenant", app="yourappid", version=2)

where resource[/scope] is the Azure resource/scope you want a token for, yourtenant is your Azure tenant name or GUID, and yourappid is your app registration ID. Note that you do not specify your username or password in the get_azure_token call.

On the server side, the app registration you use should have a mobile & desktop redirect of http://localhost:1410. See the crop below of the authentication pane for the app in the Azure portal.

Interactive authentication in a remote session

This is the scenario where you are using R in a remote terminal session of some kind: RStudio Server, Azure Databricks, or a Linux VM over ssh. Here, you still want to authenticate with your user credentials, but a browser may not be available to use the regular AAD authentication process.

The authentication flow to use is device_code. This requires that you have a browser available elsewhere (for example, on the local machine from which you’re logged in to your remote session). The code to run in your R session is

tok <- get_azure_token("resource", tenant="yourtenant", app="yourappid", auth_type="device_code")

As before, you do not include your username or password in the get_azure_token call.

On the server side, the app registration should have the “Allow public client flows” setting enabled.

It’s possible, and indeed desirable, to combine this with the previous redirect URI in the one app registration. This way, you can use the same app ID to authenticate both locally and in a remote terminal.

Interactive authentication in a webapp

This is the scenario where you want to authenticate as part of a webapp, such as a Shiny app.

For this scenario, your app registration should have a webapp redirect that has the same URL as your app, eg https://youraccount.shinyapps.io/yourapp for an app hosted in shinyapps.io. The difference between a mobile & desktop and a webapp redirect is that you supply a client secret when authenticating with the latter, but not the former. The client secret is like a password, and helps prevent third parties from hijacking your app registration.

The authentication flow to use is authorization_code, the same as for a local machine. The Shiny R code that is required is described in more detail in the ‘Authenticating from Shiny’ vignette, but essentially, the authentication is split into 2 parts: the authorization step in the UI, and then the token acquisition step on the server.

tenant <- "yourtenant"
app <- "yourappid"
redirect <- "https://yourwebsite.example.com/"

# authorization: part of UI.r
auth_uri <- build_authorization_uri("https://resource", tenant, app, redirect_uri=redirect)
redir_js <- sprintf("location.replace(\"%s\");", auth_uri)
tags$script(HTML(redir_js))

# token acquisition: part of server.R
tok <- get_azure_token("https://resource", tenant, app, password="client_secret",
                       auth_type="authorization_code", authorize_args=list(redirect_uri=redirect),
                       use_cache=FALSE, auth_code=opts$code)

Note that the password argument holds the client secret for the app registration, not a user password. See the crop below of the certificates & secrets pane for the app registration.

Be aware that the client secret is automatically generated by the server and cannot be modified. You can only see it at the time of generation, so make sure you note down its value.

Non-interactive authentication

This is the scenario where you want to authenticate to Azure without a user account present, for example in a deployment pipeline.

The authentication flow to use is client_credentials. The code to run looks like

tok <- get_azure_token("resource", tenant="yourtenant", app="yourccappid", password="client_secret")

Here, yourccappid is the app ID to use for your pipeline; you should not use the same app registration for this purpose as for interactive logins. The password argument is the client secret for your app registration, and not a user password. The client secret is set in the same way as for the interactive webapp scenario, above.

As an alternative to a client secret, it’s possible to authenticate using a TLS certificate (public key). This is considered more secure, but is also more complicated to setup. For more information, see the AAD docs linked previously.

More information

The following pages at the AAD documentation will be helpful if you’re new to creating app registrations: