Skip to content

Instantly share code, notes, and snippets.

@ORESoftware
Last active May 7, 2020 20:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ORESoftware/89a9182f1a40741384809be916bb2b0b to your computer and use it in GitHub Desktop.
Save ORESoftware/89a9182f1a40741384809be916bb2b0b to your computer and use it in GitHub Desktop.
package common
import (
"cloud.google.com/go/compute/metadata"
"encoding/json"
"errors"
"fmt"
"github.com/acme/go-api/config/proj"
jwtgo "github.com/acme/jwt-go"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"golang.org/x/oauth2/jwt"
"io/ioutil"
"net/http"
"net/url"
"path"
"strconv"
"strings"
"time"
)
var credentialFilePath = path.Join(proj.ProjectRoot, "/creds/gcloud-run-creds.json")
var credentialFile = MustReadFile(credentialFilePath)
var credentialsMap = MustParseToStringMap(credentialFile)
func ExchangeJWTForToken(signedJWT string) (string, error) {
// note: stolen from: https://medium.com/@stephen.darling/oauth2-authentication-with-google-cloud-run-700015a092c2
data := url.Values{}
data.Set("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
data.Set("assertion", signedJWT)
authUrl := "https://www.googleapis.com/oauth2/v4/token"
c := &http.Client{}
r, err := http.NewRequest("POST", authUrl, strings.NewReader(data.Encode())) // URL-encoded payload
if err != nil {
log.Error("1449a099-4b44-49c1-b770-cd9165c4b76a:", err)
return "", err
}
r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
r.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
resp, err := c.Do(r)
if err != nil {
log.Error("7c3a5b07-a58e-4906-acb0-bf4f164d7dc1:", err)
return "", err
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Error("28ed77c4-66ff-4bbb-a3f1-eddd02056359:", err)
return "", err
}
var m map[string]string
err = json.Unmarshal(body, &m)
if err != nil {
log.Error("4c5f35cb-2c28-4e2b-95ee-4bd3e72718c1:", err)
return "", err
}
if m["id_token"] == "" {
log.Error("01032228-43e6-46bd-9eb7-889f2ccc2412:", err)
return "", errors.New("78f74045-a78b-4ea6-be94-a2f67c969c92: missing 'id_token' field")
}
return m["id_token"], nil
}
func GetTmpJWT(runServiceURL string) (string, error) {
// note: stolen from: https://medium.com/@stephen.darling/oauth2-authentication-with-google-cloud-run-700015a092c2
iat := time.Now()
exp := iat.Add(time.Second * 300)
pk := credentialsMap["private_key"]
token := jwtgo.New(jwtgo.GetSigningMethod("RS256"))
token.Claims["iss"] = credentialsMap["client_email"]
token.Claims["sub"] = credentialsMap["client_email"]
token.Claims["target_audience"] = runServiceURL
token.Claims["aud"] = "https://www.googleapis.com/oauth2/v4/token"
token.Claims["iat"] = iat.Unix()
token.Claims["exp"] = exp.Unix()
tokenString, err := token.SignedString([]byte(pk))
if err != nil {
log.Error("14afe18c-d1f3-4684-9b8e-64aefd29ab5d:", err)
return "", err
}
return tokenString, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment