Skip to content

Commit

Permalink
feat(entra_id): Adds refresh_token authentication to Entra ID
Browse files Browse the repository at this point in the history
  • Loading branch information
andyquinterom committed Aug 27, 2024
1 parent d6fa4e8 commit eb9eaa3
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 7 deletions.
5 changes: 5 additions & 0 deletions R/config.R
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ request_token <- function(config, authorization_code) {
UseMethod("request_token")
}

#' @keywords internal
request_token_refresh <- function(config, refresh_token) {
UseMethod("request_token_refresh")
}

#' @title Decode a token
#' @description Decodes a token
#'
Expand Down
74 changes: 67 additions & 7 deletions R/entra_id.R
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,42 @@ request_token.entra_id_config <- function(config, authorization_code) {
client_id = config$client_id,
client_secret = config$client_secret,
grant_type = "authorization_code",
redirect_uri = config$redirect_uri
redirect_uri = config$redirect_uri,
scope = "profile openid email offline_access"
) |>
httr2::req_perform()
resp_status <- httr2::resp_status(res)
if (resp_status != 200) {
stop(httr2::resp_body_string(res))
}
resp_body <- httr2::resp_body_json(res)
access_token(config, resp_body$access_token)
list(
at = access_token(config, resp_body$access_token),
rt = resp_body$refresh_token
)
}

#' @keywords internal
request_token_refresh.entra_id_config <- function(config, refresh_token) {
res <- httr2::request(config$token_url) |>
httr2::req_method("POST") |>
httr2::req_body_form(
refresh_token = refresh_token,
client_id = config$client_id,
client_secret = config$client_secret,
grant_type = "refresh_token",
scope = "profile openid email offline_access"
) |>
httr2::req_perform()
resp_status <- httr2::resp_status(res)
if (resp_status != 200) {
stop(httr2::resp_body_string(res))
}
resp_body <- httr2::resp_body_json(res)
list(
at = access_token(config, resp_body$access_token),
rt = resp_body$refresh_token
)
}

#' @keywords internal
Expand Down Expand Up @@ -121,16 +148,18 @@ internal_add_auth_layers.entra_id_config <- function(config, tower) {
status = 302,
headers = list(
Location = config$app_url,
"Set-Cookie" = build_cookie("access_token", get_bearer(token))
"Set-Cookie" = build_cookie("access_token", get_bearer(token$at)),
"Set-Cookie" = build_cookie("refresh_token", token$rt)
)
)
},
onRejected = function(e) {
shiny::httpResponse(
status = 302,
headers = list(
Location = config$app_url,
"Set-Cookie" = build_cookie("access_token", "")
Location = get_login_url(config),
"Set-Cookie" = build_cookie("access_token", ""),
"Set-Cookie" = build_cookie("refresh_token", "")
)
)
}
Expand All @@ -143,7 +172,8 @@ internal_add_auth_layers.entra_id_config <- function(config, tower) {
status = 302,
headers = list(
Location = config$app_url,
"Set-Cookie" = build_cookie("access_token", "")
"Set-Cookie" = build_cookie("access_token", ""),
"Set-Cookie" = build_cookie("refresh_token", "")
)
)
)
Expand All @@ -163,7 +193,37 @@ internal_add_auth_layers.entra_id_config <- function(config, tower) {
return(NULL)
}
)
print(token)
if (is.null(token) && shiny::isTruthy(cookies$refresh_token)) {
# Ask for a new token using the refresh_token
token <- promises::future_promise({
request_token_refresh(config, cookies$refresh_token)
})
return(
promises::then(
token,
onFulfilled = function(token) {
shiny::httpResponse(
status = 302,
headers = list(
Location = config$app_url,
"Set-Cookie" = build_cookie("access_token", get_bearer(token$at)),
"Set-Cookie" = build_cookie("refresh_token", token$rt)
)
)
},
onRejected = function(e) {
shiny::httpResponse(
status = 302,
headers = list(
Location = get_login_url(config),
"Set-Cookie" = build_cookie("access_token", ""),
"Set-Cookie" = build_cookie("refresh_token", "")
)
)
}
)
)
}
if (is.null(token)) {
return(
shiny::httpResponse(
Expand Down

0 comments on commit eb9eaa3

Please sign in to comment.