Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow making exp claim required #351

Merged
merged 3 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions parser_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ func WithIssuedAt() ParserOption {
}
}

// WithExpirationRequired returns the ParserOption to make exp claim required.
// By default exp claim is optional.
func WithExpirationRequired() ParserOption {
return func(p *Parser) {
p.validator.requireExp = true
}
}

// WithAudience configures the validator to require the specified audience in
// the `aud` claim. Validation will fail if the audience is not listed in the
// token or the `aud` claim is missing.
Expand Down
10 changes: 10 additions & 0 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,16 @@ var jwtTestData = []struct {
jwt.NewParser(jwt.WithLeeway(2 * time.Minute)),
jwt.SigningMethodRS256,
},
{
"rejects if exp is required but missing",
"", // autogen
defaultKeyFunc,
&jwt.RegisteredClaims{},
false,
[]error{jwt.ErrTokenInvalidClaims},
jwt.NewParser(jwt.WithExpirationRequired()),
jwt.SigningMethodRS256,
},
}

// signToken creates and returns a signed JWT token using signingMethod.
Expand Down
8 changes: 6 additions & 2 deletions validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type validator struct {
// validation. If unspecified, this defaults to time.Now.
timeFunc func() time.Time

// requireExp specifies whether the exp claim is required
requireExp bool

// verifyIat specifies whether the iat (Issued At) claim will be verified.
// According to https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 this
// only specifies the age of the token, but no validation check is
Expand Down Expand Up @@ -86,8 +89,9 @@ func (v *validator) Validate(claims Claims) error {
}

// We always need to check the expiration time, but usage of the claim
oxisto marked this conversation as resolved.
Show resolved Hide resolved
// itself is OPTIONAL.
if err = v.verifyExpiresAt(claims, now, false); err != nil {
// itself is OPTIONAL by default. requireExp overrides this behavior
// and makes the exp claim mandatory.
if err = v.verifyExpiresAt(claims, now, v.requireExp); err != nil {
errs = append(errs, err)
}

Expand Down