我正在使用 Azure Webapps for Containers 来托管 R Shiny-Server。我想使用 Azure Active Directory 对登录应用的用户进行身份验证和授权。
我正在使用rocker/shiny
来自 dockerhub 的图像,并且图像可以轻松构建和运行。但是,当我打开 Active Directory 时,该应用程序不再工作。任何关于可能出错的提示和线索都会有很大帮助。
我正在使用 Azure Webapps for Containers 来托管 R Shiny-Server。我想使用 Azure Active Directory 对登录应用的用户进行身份验证和授权。
我正在使用rocker/shiny
来自 dockerhub 的图像,并且图像可以轻松构建和运行。但是,当我打开 Active Directory 时,该应用程序不再工作。任何关于可能出错的提示和线索都会有很大帮助。
我遇到了同样的“空”页面问题,因为在激活 AD 身份验证时,浏览器加载静态文件返回 HTTP 400。我在最新版本的 Shiny 服务器 (v1.5.12.933) 和 Shiny (1.4.0) 上的 Azure App Services 上的 docker 容器中有一个 Shiny 应用程序。
这意味着这里描述的问题https://community.rstudio.com/t/shiny-v1-3-known-regressions-and-serious-issues/28180/4我首先怀疑不是原因。
没有 AD 身份验证页面正确显示。负责 AD 身份验证的 Azure 代理会注入一些 HTTP 标头和 cookie。我检查了服务器端的完整 HTTP 请求,并查看了负责与 Shiny 服务器的 HTTP 连接tcpflow -p -c -i eth0 port 3838
的底层 R 库。httpuv
在搜索此库中返回 HTTP 400 代码的位置时,我发现 https://github.com/rstudio/httpuv/blob/master/src/webapplication.cpp 和以下代码片段
// Make sure that there's no message body.
if (pRequest->hasHeader("Content-Length") || pRequest->hasHeader("Transfer-Encoding")) {
return error_response(pRequest, 400);
}
而到达服务器的请求具有Content-Length: 0
如果 AD 身份验证关闭则不存在的标头。
我创建了一个修复和 PR httpuv
,请参阅问题https://github.com/rstudio/httpuv/issues/247。
只要它没有合并到他们的仓库中,您就可以使用它。
赶紧跑
R -e 'library(devtools); install_github("LHaferkamp/httpuv")'
在你的 Dockerfile
制作一个 R 文件(例如:App.R),您可以像下面这样编写代码
##################################
######### Installing libraires #################
load.lib <- c("AzureAuth","shiny","shinyjs","httr")
install.lib <- load.lib[!load.lib %in% installed.packages()]
for(lib in install.lib) install.packages(lib,dependencies=TRUE)
sapply(load.lib,library,character=TRUE)
##############################################
######### Setting the local port ###############
redirect <- "http://localhost:8100"
port <- httr::parse_url(redirect)$port
options(shiny.port=if(is.null(port)) 80 else as.numeric(port))
##################################################
######### Authentication #######################
tenant <- "your-tenant-here"
app <- "your-app-id-here"
resource <- "your-app-id-here"
token <- get_azure_token(resource, tenant, app, auth_type="authorization_code",
authorize_args=list(redirect_uri=redirect), version=2,
use_cache=FALSE)
###############Importing the app R files#########
# load ui elements
source("ui.R")
# load server function
source("server.R")
#################################################
ui_func <- function(req)
{
opts <- parseQueryString(req$QUERY_STRING)
if(is.null(opts$code))
{
auth_uri <- build_authorization_uri(resource, tenant, app, redirect_uri=redirect, version=2)
redir_js <- sprintf("location.replace(\"%s\");", auth_uri)
tags$script(HTML(redir_js))
}
else ui
}
# Run the application
shinyApp(ui = ui_func, server = server)