From 903e09573440693ee369a21363bfb03ea9b68dc0 Mon Sep 17 00:00:00 2001 From: Daniel Francesconi Date: Sun, 22 Jan 2023 04:52:42 +0100 Subject: [PATCH] Add ability to specify oidc token audience (#75) * Add ability to specify oidc token audience; Closes #65 * Move logic inside `createOIDCToken` --- oidc.go | 7 +++++-- oidc_internal_test.go | 23 +++++++++++++++++++++-- task.go | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/oidc.go b/oidc.go index 20e34f4..ef7b57f 100644 --- a/oidc.go +++ b/oidc.go @@ -71,14 +71,17 @@ func init() { OpenIDConfig.KeyID = "cloudtasks-emulator-test" } -func createOIDCToken(serviceAccountEmail string, handlerUrl string) string { +func createOIDCToken(serviceAccountEmail string, handlerUrl string, audience string) string { + if audience == "" { + audience = handlerUrl + } now := time.Now() claims := OpenIDConnectClaims{ Email: serviceAccountEmail, EmailVerified: true, StandardClaims: jwt.StandardClaims{ Subject: serviceAccountEmail, - Audience: handlerUrl, + Audience: audience, Issuer: OpenIDConfig.IssuerURL, IssuedAt: now.Unix(), NotBefore: now.Unix(), diff --git a/oidc_internal_test.go b/oidc_internal_test.go index 87970e1..0a0ff5c 100644 --- a/oidc_internal_test.go +++ b/oidc_internal_test.go @@ -14,7 +14,7 @@ import ( ) func TestCreateOIDCTokenSetsCorrectData(t *testing.T) { - tokenStr := createOIDCToken("foobar@service.com", "http://my.service/foo?bar=v") + tokenStr := createOIDCToken("foobar@service.com", "http://my.service/foo?bar=v", "") parser := new(jwt.Parser) token, _, err := parser.ParseUnverified(tokenStr, &OpenIDConnectClaims{}) require.NoError(t, err) @@ -33,9 +33,28 @@ func TestCreateOIDCTokenSetsCorrectData(t *testing.T) { assertRoughTimestamp(t, 5*time.Minute, claims.ExpiresAt, "Expires in 5 mins") } +func TestCreateOIDCTokenWithCustomAudienceSetsCorrectData(t *testing.T) { + tokenStr := createOIDCToken("foobar@service.com", "http://my.service/foo?bar=v", "http://my.api") + parser := new(jwt.Parser) + token, _, err := parser.ParseUnverified(tokenStr, &OpenIDConnectClaims{}) + require.NoError(t, err) + assert.Equal(t, "RS256", token.Header["alg"], "Uses RS256") + assert.Equal(t, OpenIDConfig.KeyID, token.Header["kid"], "Specifies kid") + + claims := token.Claims.(*OpenIDConnectClaims) + + assert.Equal(t, "http://my.api", claims.Audience, "Specifies audience") + assert.Equal(t, OpenIDConfig.IssuerURL, claims.Issuer, "Specifies issuer") + assert.Equal(t, "foobar@service.com", claims.Email, "Specifies email") + assert.True(t, claims.EmailVerified, "Specifies email") + assertRoughTimestamp(t, 0*time.Second, claims.IssuedAt, "Issued now") + assertRoughTimestamp(t, 0*time.Second, claims.NotBefore, "Not before now") + assertRoughTimestamp(t, 5*time.Minute, claims.ExpiresAt, "Expires in 5 mins") +} + func TestCreateOIDCTokenSignatureIsValidAgainstKey(t *testing.T) { // Sanity check that the token is valid if we have the private key in go format - tokenStr := createOIDCToken("foobar@service.com", "http://any.service/foo") + tokenStr := createOIDCToken("foobar@service.com", "http://any.service/foo", "") _, err := new(jwt.Parser).ParseWithClaims( tokenStr, &OpenIDConnectClaims{}, diff --git a/task.go b/task.go index 01c134f..966696e 100644 --- a/task.go +++ b/task.go @@ -312,7 +312,7 @@ func dispatch(retry bool, taskState *tasks.Task) int { headers = httpRequest.GetHeaders() if auth := httpRequest.GetOidcToken(); auth != nil { - tokenStr := createOIDCToken(auth.ServiceAccountEmail, httpRequest.GetUrl()) + tokenStr := createOIDCToken(auth.ServiceAccountEmail, httpRequest.GetUrl(), auth.Audience) headers["Authorization"] = "Bearer " + tokenStr }