jwt-go icon indicating copy to clipboard operation
jwt-go copied to clipboard

Adding JWT Audience to support array of audiences

Open farajfarook opened this issue 6 years ago • 10 comments

Audience claim in JWT should support a list of audiences

Refer https://tools.ietf.org/html/rfc7519#section-4.1.3

4.1.3. "aud" (Audience) Claim

The "aud" (audience) claim identifies the recipients that the JWT is intended for. Each principal intended to process the JWT MUST identify itself with a value in the audience claim. If the principal processing the claim does not identify itself with a value in the "aud" claim when this claim is present, then the JWT MUST be rejected. In the general case, the "aud" value is an array of case- sensitive strings, each containing a StringOrURI value. In the special case when the JWT has one audience, the "aud" value MAY be a single case-sensitive string containing a StringOrURI value. The interpretation of audience values is generally application specific. Use of this claim is OPTIONAL.

farajfarook avatar Nov 27 '18 04:11 farajfarook

if you just arrived at this problem and you are blocked by this fact, remember that you can use jwt.ParseWithClaims which accepts a different struct to be Unmarshalled, and you can extend your struct to have audience as an array. In my case we needed to even support a irregular JSON, which lead me to this: https://play.golang.org/p/-nuVjhE3uKP

👍 hope to see this merged soon

PS: Besides changing the validation, I guess it would be good to allow the default Claims to Unmarshall the aud either as string or array.

Here is the hack that I used for now:

// KeycloakClaims describes the token payload from Key Cloak
type KeycloakClaims struct {
	Audience       multiString               `json:"aud,omitempty"`
}

// multiString is a temporary necessity to allow receiving the claim
// aud from the token with either string or array. There is a PR opened
// on jwt-go that once merged, this code can be removed and we can use only
// slice of strings for the audience
type multiString string

func (ms *multiString) UnmarshalJSON(data []byte) error {
	if len(data) > 0 {
		switch data[0] {
		case '"':
			var s string
			if err := json.Unmarshal(data, &s); err != nil {
				return err
			}
			*ms = multiString(s)
		case '[':
			var s []string
			if err := json.Unmarshal(data, &s); err != nil {
				return err
			}
			*ms = multiString(strings.Join(s, ","))
		}
	}
	return nil
}

ghophp avatar May 21 '19 10:05 ghophp

It would be great to have this PR merged as this functionality is something I am looking for as well. What can be done to move this along?

grounded042 avatar Jul 19 '19 20:07 grounded042

Is there any plans to merge that PR soon? I am facing the same problem and this will make my life easier :)

michaelchemani avatar Aug 07 '19 14:08 michaelchemani

@dgrijalva Do you have any updates on my PR?

farajfarook avatar Sep 15 '19 06:09 farajfarook

Any plans to (ever) merge this?

SnirShechter avatar Dec 16 '19 12:12 SnirShechter

i needed this as well but just to create a JWT (not as in this PR to verify). But, yeah, it'd be nice to include this in.

type MyCustomClaims struct {
	Uid string   `json:"uid"`
	Aud []string `json:"aud"`
	jwt.StandardClaims
}

	claims := MyCustomClaims{
		"alice",
		[]string{"http://fe.default.svc.cluster.local:8080/", "http://be.default.svc.cluster.local:8080/"},
		jwt.StandardClaims{
			Issuer:    "someissuer",
			Subject:   "somesubject",
			IssuedAt:  time.Now().Unix(),
			ExpiresAt: time.Now().Add(time.Minute * 5).Unix(),
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)

gives a jwt like

{
  "uid": "alice",
  "aud": [
    "http://fe.default.svc.cluster.local:8080/",
    "http://be.default.svc.cluster.local:8080/"
  ],
  "exp": 1583547451,
  "iat": 1583547151,
  "iss": "someissuer",
  "sub": "somesubject"
}

fwiw, envoyproxy's jwt validator can process an inbound jwt in that format

salrashid123 avatar Mar 07 '20 02:03 salrashid123

+1 to built-in support for an array of audiences.

j-fuentes avatar Apr 08 '20 15:04 j-fuentes

@dgrijalva attention please!

integrii avatar Oct 21 '20 08:10 integrii

+1 This would be really useful

chronark avatar Jan 17 '21 13:01 chronark

@dgrijalva could we get this merged in please?

ProBun avatar May 24 '21 22:05 ProBun