Azure / AzureAuth

R package for OAuth 2.0 authentication with Azure Active Directory
Other
41 stars 15 forks source link

Azure auth web page continuously open in the browser without stopping #83

Open liqi6811 opened 9 months ago

liqi6811 commented 9 months ago

Hi team,

I tried code vignettes/shiny.Rmd, but the Azure auth web page continuously open in the browser without stopping, how to resolve it?

Thanks, Ling

tylerlittlefield commented 9 months ago

I'm also interested in this. I actually helped make the shiny vignette but I've always run into this infinite loop when trying to debug SSO locally.

PhilippPro commented 7 months ago

I had the same.

hongooi73 commented 7 months ago

@tylerlittlefield @liqi6811 is this still happening? Sometimes Azure can be glitchy.

liqi6811 commented 7 months ago

@hongooi73 Yes, it is still happening, do not know how to solve it.

tylerlittlefield commented 6 months ago

@hongooi73 yes, this still happens to me as well

liqi6811 commented 6 months ago

Hi all,

I found how to solve infinite loop issue. The code is developed based on Hadley's shiny-oauth.r

from the original code, aleszib mentioned the code works fine in "Externa" but not in RStudio viewer plan. So, I just published the code to shinyapps.io and the Azure authentication works. Just to make sure your actually app code is working, then add your ui to ui, and your server logic to server after token generated. Sample code as below:

library(AzureAuth)
library(shiny)
library(shinyjs)

tenant <- tenant_ID # replace with your tenant ID
app <- app_ID # replace with your app ID
client_secret <- CLIENT_SECRET # replace with your client secret

resource <- c(https://management.azure.com/.default, "openid")
redirect <- https://xxxxx.shinyapps.io/yyyyy # replace with your uri which has been added to Entra

ui<-fluidPage(
  # input your ui
  titlePanel("Hello Shiny!"),
  sidebarLayout(position = "right",
                sidebarPanel(
                  sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
                ),
                mainPanel(
                  plotOutput("distPlot")
                )
  )
)

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
}

# code for cleaning url after authentication
clean_url_js <- sprintf(
  "
    $(document).ready(function(event) {
      const nextURL = '%s';
      const nextTitle = 'My new page title';
      const nextState = { additionalInformation: 'Updated the URL with JS' };
      // This will create a new entry in the browser's history, without reloading
      window.history.pushState(nextState, nextTitle, nextURL);
    });
    ", redirect
)

server <- function(input, output, session)
{
  shinyjs::runjs(clean_url_js)

  opts <- parseQueryString(isolate(session$clientData$url_search))
  if(is.null(opts$code))
    return()

  token <- get_azure_token(resource, tenant, app, password=client_secret, auth_type="authorization_code",
                           authorize_args=list(redirect_uri=redirect), version=2,
                           use_cache=FALSE, auth_code=opts$code)

  # input your server logic 
  output$distPlot <- renderPlot({
    x    <- faithful[, 2]  # Old Faithful Geyser data
    bins <- seq(min(x), max(x), length.out = input$bins + 1)

    # draw the histogram with the specified number of bins
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
}

shinyApp(ui_func, server)

I do not know why it does not work in RStudio viewer, please share if anybody knows.

PhilippPro commented 6 months ago

We could run the code locally in RStudio by setting a redirected Variable in the code to avoid that the redirection is done continously.

So we set redirected <- FALSE at the beginning and then in the ui_func function we set the following (instead of if(is.null(opts$code)){ :

  if (!redirected && is.null(opts$code)) {
    redirected <<- TRUE  # Set the flag to indicate redirection has occurred