jwt-go
jwt-go copied to clipboard
Adding JWT Audience to support array of audiences
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.
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
}
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?
Is there any plans to merge that PR soon? I am facing the same problem and this will make my life easier :)
@dgrijalva Do you have any updates on my PR?
Any plans to (ever) merge this?
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
+1 to built-in support for an array of audiences.
@dgrijalva attention please!
+1 This would be really useful
@dgrijalva could we get this merged in please?