Replies: 2 comments 2 replies
-
There are basically two options:
type MyClaims struct {
jwt.RegisteredClaims
This *string
That *string
TheOther *int
} and then check for the existence in
type MyClaims jwt.MapClaims
func (m MyClaims) Validate error() {
// Just use the map here
value, ok := m["my claim"]
} You might need to explicitly cast Update: no cast needed, you can just directly access the map values this way. |
Beta Was this translation helpful? Give feedback.
2 replies
-
Hi @johakoch, I've put together a proof of concept based on the code provided above. This has not been fully tested, and may not be fully performant, but I believe it does what you require for now; package main
import (
"encoding/json"
"fmt"
"log"
"github.com/golang-jwt/jwt/v5"
)
// Embed the jwt.MapClaims type to ensure the methods are available to
// satisfy the jwt.Claims and jwt.ClaimsValidator interfaces.
type MyClaims struct {
jwt.MapClaims
// This could potentially be extended to include expected values.
// ExpectedClaims map[string]any....
// You could also define an "expectedclaim" type, with properties for
// 'expected', 'required/optional' etc.
}
// Custom validation done in this function
func (m MyClaims) Validate() error {
_, ok := m.MapClaims["my_claim"]
if !ok {
return fmt.Errorf("missing my_claim")
}
return nil
}
// Implement a custom unmarshal function for this type, to ensure that the claims
// are copied to MyClaims.MapClaims
func (m *MyClaims) UnmarshalJSON(b []byte) error {
t := new(map[string]any)
if err := json.Unmarshal(b, t); err != nil {
return err
}
if m.MapClaims == nil {
m.MapClaims = jwt.MapClaims{}
}
for claim, value := range *t {
m.MapClaims[claim] = value
}
return nil
}
func main() {
// Validate that the supported, existing ParserOptions still function as intended.
p := jwt.NewParser(jwt.WithIssuer("acme"))
tok := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"aud": "peter",
"a": 1,
"iss": "not_acme",
})
keyBytes := []byte("mySecretK3y")
token, _ := tok.SignedString(keyBytes)
claims := MyClaims{jwt.MapClaims{}}
// Expected output:
// '2009/11/10 23:00:00 token has invalid claims: token has invalid issuer, missing my_claim'
parsedToken, err := p.ParseWithClaims(token, &claims, func(_ *jwt.Token) (interface{}, error) {
return keyBytes, nil
})
if err != nil {
log.Fatal(err)
}
log.Printf("This is my token: %+v", parsedToken)
} Does this answer your question / partially solve your use case? |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
The
ClaimsValidator
interface provides a way to have a claims implementation that has its own (additional) claims validation. The examples I see in code are all using thejwt.RegisteredClaims
as a base, extending by a specific claim.What about the case where you have arbitrary additional claims, the expected values of which (to be validated against) you only know at run time because they are e.g. read from a configuration?
Currently I use
jwt.MapClaims
as input toParseWithClaims()
and then validate the claims after parsing. How could I do it during parsing with theClaimsValidator
interface?Beta Was this translation helpful? Give feedback.
All reactions