【问题标题】:How do I get Shiny-server to working with Azure Active Directory如何让 Shiny-server 使用 Azure Active Directory
【发布时间】:2019-11-09 19:54:51
【问题描述】:

我正在使用 Azure Webapps for Containers 来托管 R Shiny-Server。我想使用 Azure Active Directory 对登录应用的用户进行身份验证和授权。

我正在使用来自 dockerhub 的 rocker/shiny 映像,并且该映像可以轻松构建和运行。但是,当我打开 Active Directory 时,该应用程序不再工作。任何关于可能出错的提示和线索都会有很大帮助。

【问题讨论】:

  • 目前有同样的问题。你找到解决办法了吗?

标签: r shiny azure-active-directory shiny-server azure-webapps


【解决方案1】:

我遇到了同样的“空”页面问题,因为在激活 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。我通过tcpflow -p -c -i eth0 port 3838 在服务器端检查了完整的HTTP 请求,并查看了负责与Shiny 服务器的HTTP 连接的底层R 库httpuv

在搜索此库中返回 HTTP 400 代码的位置时,我发现 https://github.com/rstudio/httpuv/blob/master/src/webapplication.cpp 和下面的代码sn-p

// 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 身份验证关闭,则该标头不存在。

我为 httpuv 创建了修复和 PR,请参阅问题 https://github.com/rstudio/httpuv/issues/247

只要没有合并到他们的仓库中,你就可以使用它。

快跑

R -e 'library(devtools); install_github("LHaferkamp/httpuv")'

在你的 Dockerfile 中

【讨论】:

  • 非常感谢您的回答@lhaferkamp。虽然我使用了来自 CRAN 的最新 httpuv,但仍然遇到同样的问题,尽管标头响应中的 Content-Length 是 16 而不是 0。因此按照您的代码 sn-p,逻辑上也会返回 400 Bad Request。所以不幸的是我猜仍然没有适当的解决方案?
  • @Marco:到目前为止,带有我的修复程序的 httpuv 版本尚未发布到 R CRAN 存储库。我在 Github 上询问何时发布修复程序,他们告诉我 4 月底。所以我也在等待最终删除我的解决方法。现在已经半年了,所以那里的发布周期真的很慢:(
  • httpuv的新版本出来了,我可以用那个版本验证,这个问题现在已经修复了
【解决方案2】:

制作一个 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)

【讨论】:

  • 纯代码答案并不是特别有用,而且通常是复杂用例的安全问题。请编辑您的答案,以包括您的解决方案的来源和描述以及它的作用。
猜你喜欢
  • 2019-03-21
  • 1970-01-01
  • 2023-01-13
  • 2020-03-27
  • 2022-01-18
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多