如何让Shiny-server与Azure Active Directory一起工作

rt4zxlrg  于 2022-12-25  发布在  其他
关注(0)|答案(2)|浏览(163)

我正在使用Azure Webapps for Containers托管R Shiny-Server。我希望使用Azure Active Directory对登录该应用的用户进行身份验证和授权。
我正在使用DockerHub的rocker/shiny映像,映像构建和运行都很容易。但是,当我打开Active Directory时,应用程序不再工作。任何关于可能出错的提示和线索都会有很大帮助。

mwkjh3gx

mwkjh3gx1#

我遇到了同样的“空”页面问题,因为在激活AD身份验证时,浏览器加载静态文件返回HTTP 400。我在最新版本的Shiny服务器(v1.5.12.933)和Shiny(1.4.0)上的Azure应用服务上的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请求,并查看了底层R库httpuv,该库负责与Shiny服务器的HTTP连接。
在搜索这个库中HTTP400代码的返回位置时,我找到了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认证被关闭,则该报头不存在。
我为httpuv创建了一个修复程序和PR,请参见问题https://github.com/rstudio/httpuv/issues/247
你可以使用它,只要它不合并到他们的回购。
快跑
R -e 'library(devtools); install_github("LHaferkamp/httpuv")'
在您的Dockerfile中

abithluo

abithluo2#

首先,你需要在Azure应用注册服务中注册你的应用并获取租户和应用ID。有关详细信息,请阅读this。你可以通过AzureAuth库中的get_azure_token函数使用Azure Active Directory。请阅读有关参数here的详细信息。

##################################
######### 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 from Azure app service"
app <- "your-app-id-here from azure app service"
resource <- "your-scopes-here"
#example 
resource <- c("https://graph.microsoft.com/User.Read.All",
                  "https://graph.microsoft.com/User.ReadWrite.All",
                  "https://graph.microsoft.com/Directory.ReadWrite.All",
                  "offline_access")
pass = "your secret that you generate in the Azure app regitration"
aad_host = "https://login.microsoftonline.com/common/oauth2"

Token <- AzureAuth::get_azure_token( resource,tenant,
                                       app,
                                       password = pass,
                                       auth_type="authorization_code",
                                       authorize_args=list(redirect_uri=redirect),
                                       use_cache=FALSE,
                                       auth_code=opts$code,
                                       version = 2,
                                       aad_host = aad_host
  )

###############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)

我试着在上面代码的注解中解释每个因素。如果你使用版本=1验证,你需要保存访问令牌,并在代码中的某个地方刷新令牌,并在过期后获得一个新的访问令牌。如果你使用版本=2,只需在服务器.R中的某处刷新Token$,它就会扩展您的证书。最后的func函数是如果用户没有通过认证,则建立azure授权登录页面。

相关问题