Skip to content

Commit

Permalink
#7 example for scoped auth with JWT
Browse files Browse the repository at this point in the history
  • Loading branch information
Friedrike Preu committed Mar 2, 2019
1 parent 325629e commit 68687d0
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 5 deletions.
19 changes: 16 additions & 3 deletions R/jwt.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
#' @param res Response object.
#' @param secret character. This should be the secret that use to sign your JWT. The secret is converted
#' to raw bytes in the function.
#' @param audience character. Check if user belongs to a certain audience.
#' @param claims_to_check names list of claims to check.
#'
#' @importFrom stringr str_remove str_trim
#' @importFrom jose jwt_decode_hmac
#' @importFrom plumber forward
#' @importFrom purrr map2
#'
#' @examples
#' \dontrun{
Expand All @@ -23,7 +24,7 @@
#' @export
#'

jwt <- function (req, res, secret, audience = NULL) {
jwt <- function (req, res, secret, audience = NULL, claims_to_check = NULL) {

# ensure that the user passed the request object
if (missing(req) == TRUE)
Expand All @@ -37,6 +38,9 @@ jwt <- function (req, res, secret, audience = NULL) {
if (nchar(secret) < 1)
warning("Your secret is empty. This is a possible security risk.")

if (!is.null(claims_to_check) && !is.list(claims_to_check)) {
stop("claims_to_check needs to be a named list of claims to check.")
}
# convert secret to bytes
secret <- charToRaw(secret)

Expand Down Expand Up @@ -64,7 +68,11 @@ jwt <- function (req, res, secret, audience = NULL) {
message="Authentication required."))
}

# check if audience correct
# check if custom claims correct
if (!is.null(claims_to_check)) {
purrr::map2(names(claims_to_check), claims_to_check, check_claim, token = token)
}

if (!is.null(audience)) {
if (audience != token$aud) {
res$status <- 401
Expand All @@ -77,3 +85,8 @@ jwt <- function (req, res, secret, audience = NULL) {
# redirect to routes
plumber::forward()
}

check_claim <- function(claim_name, claim_value, token){
token_claim_value <- tryCatch(token[[claim_name]], error = function (e) NULL)
return(identical(token[[claim_name]], claim_value))
}
32 changes: 32 additions & 0 deletions examples/jwt/jwt_audience_example/README.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
output: github_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

# JWT Audience Example

JWT often include an "audience" claim that specifies the role and permissions of a user. Depending on this claim, we
can make different routes available to different users.

## R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.

When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

```{r cars}
summary(cars)
```

## Including Plots

You can also embed plots, for example:

```{r pressure, echo=FALSE}
plot(pressure)
```

Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,10 @@ pr$handle("GET", "/", function (req, res) {
}, preempt = c("sealr-jwt"))



# define test route with authentication
pr$handle("GET", "/secret", function (req, res) {
return(iris[101:150, ])
})

# start API server
pr$run(host="0.0.0.0", port=9090)
pr$run(host = "0.0.0.0", port = 9090)

0 comments on commit 68687d0

Please sign in to comment.