Skip to content

Instantly share code, notes, and snippets.

@salrashid123
Last active March 10, 2022 18:12
Show Gist options
  • Save salrashid123/5b1250109f09447b2fa820bc3f7e340d to your computer and use it in GitHub Desktop.
Save salrashid123/5b1250109f09447b2fa820bc3f7e340d to your computer and use it in GitHub Desktop.
golang iam signjwt
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"time"
credentials "cloud.google.com/go/iam/credentials/apiv1"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1"
)
const ()
var ()
// /home/srashid/gcp_misc/certs/mineral-minutia-820-e9a7c8665867.json
func main() {
ctx := context.Background()
c, err := credentials.NewIamCredentialsClient(ctx)
if err != nil {
panic(err)
}
defer c.Close()
targetPrincipal := "[email protected]"
now := time.Now()
cc := &claimSet{
Iss: targetPrincipal,
Iat: now.Unix(),
Exp: now.Add(time.Hour).Unix(),
Scope: "https://www.googleapis.com/auth/cloud-platform",
//Aud: "https://oauth2-dev01.p.googleapis.com/token",
Aud: google.Endpoint.TokenURL,
}
b, err := json.Marshal(cc)
if err != nil {
panic(err)
}
name := fmt.Sprintf("projects/-/serviceAccounts/%s", targetPrincipal)
req := &credentialspb.SignJwtRequest{
Name: name,
Payload: string(b),
}
resp, err := c.SignJwt(ctx, req)
if err != nil {
panic(err)
}
fmt.Printf("SignedJWT: %s\n", resp.SignedJwt)
var hc = oauth2.NewClient(ctx, nil)
var v = url.Values{}
v.Set("grant_type", "assertion")
v.Set("assertion_type", "http://oauth.net/grant_type/jwt/1.0/bearer")
v.Set("assertion", resp.SignedJwt)
rr, err := hc.PostForm(google.JWTTokenURL, v)
if err != nil {
panic(err)
}
defer rr.Body.Close()
body, err := ioutil.ReadAll(io.LimitReader(rr.Body, 1<<20))
if err != nil {
panic(err)
}
if c := rr.StatusCode; c != http.StatusOK {
fmt.Printf("invalid exchange response ")
return
}
var tokenRes struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
IDToken string `json:"id_token"`
ExpiresIn int64 `json:"expires_in"`
}
if err := json.Unmarshal(body, &tokenRes); err != nil {
panic(err)
}
accessToken := tokenRes.AccessToken
now = time.Now()
now.Add(time.Second * time.Duration(tokenRes.ExpiresIn))
expireAt := now
if err != nil {
panic(err)
}
ts := &oauth2.Token{
AccessToken: accessToken,
Expiry: expireAt,
}
fmt.Printf("AccessToken: %s\n", ts.AccessToken)
}
type claimSet struct {
Iss string `json:"iss"`
Scope string `json:"scope,omitempty"`
Aud string `json:"aud"`
Exp int64 `json:"exp"`
Iat int64 `json:"iat"`
Typ string `json:"typ,omitempty"`
Sub string `json:"sub,omitempty"`
Prn string `json:"prn,omitempty"`
PrivateClaims map[string]interface{} `json:"-"`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment