Create provider settings for Microsoft Entra ID. Choose which accounts may
sign in with tenant, then pass the provider and your own registered app's
credentials to oauth_client().
Usage
oauth_provider_microsoft(
name = "microsoft",
tenant = c("common", "organizations", "consumers"),
id_token_validation = NULL
)Arguments
- name
Optional friendly name for the provider. Defaults to "microsoft"
- tenant
Tenant identifier ("common", "organizations", "consumers", or directory GUID). Defaults to "common"
- id_token_validation
Optional override (logical). If
NULL(default), it's enabled automatically whentenantlooks like a GUID or one of the Microsoft alias tenants (common,organizations,consumers).commonandorganizationsuse Microsoft's tenant-independent issuer and signing-key validation rules;consumersuses the stable consumer tenant issuer
Value
OAuthProvider object configured for Microsoft identity platform
Details
Use a directory (tenant) ID to target one organization. "organizations"
allows work or school accounts, "consumers" allows personal Microsoft
accounts, and "common" allows both. Your app registration and app access
rules must also permit the intended accounts.
ID token validation is enabled for these tenant choices. For a directory ID,
the issuer must match that directory. "common" and "organizations" use
Microsoft's tenant-independent issuer template and signing-key issuer rules.
"consumers" uses the consumer tenant issuer. The helper restricts ID token
algorithms to RS256 and fetches userinfo from Microsoft Graph.
Setting id_token_validation = FALSE disables ID token and nonce checks and
leaves OAuth plus profile retrieval. Keep the default for OIDC sign-in.
Tenant domains and other unrecognized tenant identifiers require this
explicit opt-out; otherwise use the directory GUID to retain OIDC validation.
Examples
if (
# Example requires configured Microsoft Entra ID (Azure AD) tenant:
nzchar(Sys.getenv("MS_TENANT")) &&
interactive() &&
requireNamespace("later", quietly = TRUE)
) {
library(shiny)
library(shinyOAuth)
# Configure provider and client (Microsoft Entra ID with your tenant)
client <- oauth_client(
provider = oauth_provider_microsoft(
# Provide your own tenant ID here (set as environment variable MS_TENANT)
tenant = Sys.getenv("MS_TENANT")
),
# Azure CLI public-client app ID; the tenant must permit this app.
# For your deployed app, use your own registration and redirect URI:
client_id = "04b07795-8ddb-461a-bbee-02f9e1bf7b46",
client_secret = "",
redirect_uri = "http://localhost:8100",
scopes = c("openid", "profile", "email")
)
# UI
ui <- oauth_ui(
fluidPage(
h3("OAuth demo (Microsoft Entra ID)"),
uiOutput("oauth_error"),
tags[["hr"]](),
h4("Auth object (summary)"),
verbatimTextOutput("auth_print"),
tags[["hr"]](),
h4("User info"),
verbatimTextOutput("user_info")
),
id = "auth",
client = client
)
# Server
server <- function(input, output, session) {
auth <- oauth_module_server("auth", client)
output[["auth_print"]] <- renderText({
authenticated <- auth[["authenticated"]]
tok <- auth[["token"]]
err <- auth[["error"]]
paste0(
"Authenticated?",
if (isTRUE(authenticated)) " YES" else " NO",
"\n",
"Has token? ",
if (!is.null(tok)) "YES" else "NO",
"\n",
"Has error? ",
if (!is.null(err)) "YES" else "NO",
"\n\n",
"Token present: ",
!is.null(tok),
"\n",
"Has refresh token: ",
!is.null(tok) && isTRUE(nzchar(tok@refresh_token)),
"\n",
"Has ID token: ",
!is.null(tok) && !is.na(tok@id_token),
"\n",
"Expires at: ",
if (!is.null(tok)) tok@expires_at else "N/A"
)
})
output[["user_info"]] <- renderPrint({
req(auth[["authenticated"]])
auth[["token"]]@userinfo
})
observeEvent(
list(auth[["error"]], auth[["error_description"]]),
{
if (interactive() && !is.null(auth[["error_description"]])) {
rlang::inform(c(
"OAuth error details",
"i" = paste0("error: ", auth[["error"]]),
"i" = paste0("error_description: ", auth[["error_description"]])
))
}
},
ignoreInit = TRUE
)
output[["oauth_error"]] <- renderUI({
if (is.null(auth[["error"]])) {
return(NULL)
}
msg <- if (identical(auth[["error"]], "access_denied")) {
"Sign-in was canceled or denied. Please try again."
} else {
"Authentication failed. Please try again."
}
div(class = "alert alert-danger", role = "alert", msg)
})
}
# Need to open app in 'localhost:8100' to match with redirect_uri
# of the public Azure CLI app (above). Browser must use 'localhost'
# too to properly set the browser cookie. But Shiny only redirects to
# '127.0.0.1' & blocks process once it runs. So we disable browser
# launch by Shiny & then use 'later::later()' to open the browser
# ourselves a short moment after the app starts
later::later(
function() {
utils::browseURL("http://localhost:8100")
},
delay = 0.25
)
# Run app
runApp(shinyApp(ui, server), port = 8100, launch.browser = FALSE)
}