I try to generate JWT for google-oauth2.0 ServiceAccount.
I set up header and payload (claim). But when I try to sigh base64header.base64claim with RSASHA256 I get incorrect signature. I found only one function in PKI package that alows to sign contet with RSA with specified hash function.
How did I figure that my signature incorrect? I found resource that can generate JWT from inputs and private KEY.
So all I can see, that my signture from R functions differs from jwt.io signature. I've tested requests for https://www.googleapis.com/oauth2/v3/token with both of JWT tokens, and jwt.io one was working.
This part is for JWT header.
library(base64enc)
library(jsonlite)
library(PKI)
#JWT header set up
alg <- "RS256"
typ <- "JWT"
header <- list("alg" = alg, "typ" = typ)
h <- toJSON(header, auto_unbox=TRUE)
enc.header <- base64encode(charToRaw(h))
This part is for JWT claim (payload)
iss <- "165724828594-mkuchqogmjapbl7mpfn0e7f7o3qlrqsr@developer.gserviceaccount.com"
scope <- "https://www.googleapis.com/auth/analytics.readonly"
aud <- "https://www.googleapis.com/oauth2/v3/token"
iat <- as.integer(as.POSIXct(Sys.time()))
exp <- iat+3600
claim <- list("iss" = iss, "scope" = scope, "aud" = aud, "exp" = exp, "iat" = iat)
cl <- toJSON(claim, auto_unbox=TRUE)
enc.claim <- base64encode(charToRaw(cl))
And this is my problem.
y <- file("~/keys/euroset-test-70c2d0d4eed1.pem")
key <- PKI.load.key(y)
what <- paste(enc.header,enc.claim, sep=".")
JWS <- PKI.sign(what, key, "SHA256")
enc.sign <- base64encode(JWS)
JWT <- paste(what,enc.sign, sep=".")
JWT
Any help, please? I've stucked with JWS for 4 days already.(
Finally I've found a problem place. It's always been about base64encoding. I've checked Correct and Inctorrect JWTs and found some pattern. Incorrect one have had "=="
in payload and signature, I've replaced it with ""
. Also in signature all "/"
I've replaced with "_"
, and all "+"
with "-"
. Hope it will give a hint to peopple with the same issue.
https://github.com/hadley/httr/blob/master/R/oauth-server-side.R
This is the code for getting the token which works for some of the Google APIs (but not for the cloud which is what I need.. let me know if you got it working). Also, the httr oauth_service_token is a lot easier to use than coding your own.
init_oauth_service_account <- function(endpoint, secrets, scope = NULL) {
signature <- jwt_signature(secrets, scope = scope)
res <- POST(endpoint$access, body = list(
grant_type = "urn:ietf:params:oauth:grant-type:jwt-bearer",
assertion = signature
), encode = "form")
stop_for_status(res)
content(res, type = "application/json")
}
...
jwt_base64 <- function(x) base64url(jwt_json(x))
jwt_json <- function(x) jsonlite::toJSON(x, auto_unbox = TRUE)
base64url <- function(x) {
if (is.character(x)) {
x <- charToRaw(x)
}
out <- chartr('+/', '-_', base64enc::base64encode(x))
gsub("=+$", "", out)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.