* implement SASL OAUTHBEARER and draft/bearer * Upgrade JWT lib * Fix an edge case in SASL EXTERNAL * Accept longer SASL responses * review fix: allow multiple token definitions * enhance tests * use SASL utilities from irc-go * test expired tokens
8.5 KiB
Migration Guide (v5.0.0)
Version v5
contains a major rework of core
functionalities in the jwt-go
library. This includes
support for several validation options as well as a re-design of the
Claims
interface. Lastly, we reworked how errors work under
the hood, which should provide a better overall developer
experience.
Starting from v5.0.0, the import path will be:
"github.com/golang-jwt/jwt/v5"
For most users, changing the import path should suffice. However, since we intentionally changed and cleaned some of the public API, existing programs might need to be updated. The following sections describe significant changes and corresponding updates for existing programs.
Parsing and Validation Options
Under the hood, a new Validator
struct takes care of
validating the claims. A long awaited feature has been the option to
fine-tune the validation of tokens. This is now possible with several
ParserOption
functions that can be appended to most
Parse
functions, such as ParseWithClaims
. The
most important options and changes are: * Added WithLeeway
to support specifying the leeway that is allowed when validating
time-based claims, such as exp
or nbf
. *
Changed default behavior to not check the iat
claim. Usage
of this claim is OPTIONAL according to the JWT RFC. The claim itself is
also purely informational according to the RFC, so a strict validation
failure is not recommended. If you want to check for sensible values in
these claims, please use the WithIssuedAt
parser option. *
Added WithAudience
, WithSubject
and
WithIssuer
to support checking for expected
aud
, sub
and iss
. * Added
WithStrictDecoding
and WithPaddingAllowed
options to allow previously global settings to enable base64 strict
encoding and the parsing of base64 strings with padding. The latter is
strictly speaking against the standard, but unfortunately some of the
major identity providers issue some of these incorrect tokens. Both
options are disabled by default.
Changes to the
Claims
interface
Complete Restructuring
Previously, the claims interface was satisfied with an implementation
of a Valid() error
function. This had several issues: * The
different claim types (struct claims, map claims, etc.) then contained
similar (but not 100 % identical) code of how this validation was done.
This lead to a lot of (almost) duplicate code and was hard to maintain *
It was not really semantically close to what a “claim” (or a set of
claims) really is; which is a list of defined key/value pairs with a
certain semantic meaning.
Since all the validation functionality is now extracted into the
validator, all VerifyXXX
and Valid
functions
have been removed from the Claims
interface. Instead, the
interface now represents a list of getters to retrieve values with a
specific meaning. This allows us to completely decouple the validation
logic with the underlying storage representation of the claim, which
could be a struct, a map or even something stored in a database.
type Claims interface {
() (*NumericDate, error)
GetExpirationTime() (*NumericDate, error)
GetIssuedAt() (*NumericDate, error)
GetNotBefore() (string, error)
GetIssuer() (string, error)
GetSubject() (ClaimStrings, error)
GetAudience}
Users that previously directly called the Valid
function
on their claims, e.g., to perform validation independently of
parsing/verifying a token, can now use the jwt.NewValidator
function to create a Validator
independently of the
Parser
.
var v = jwt.NewValidator(jwt.WithLeeway(5*time.Second))
.Validate(myClaims) v
Supported
Claim Types and Removal of StandardClaims
The two standard claim types supported by this library,
MapClaims
and RegisteredClaims
both implement
the necessary functions of this interface. The old
StandardClaims
struct, which has already been deprecated in
v4
is now removed.
Users using custom claims, in most cases, will not experience any
changes in the behavior as long as they embedded
RegisteredClaims
. If they created a new claim type from
scratch, they now need to implemented the proper getter functions.
Migrating
Application Specific Logic of the old Valid
Previously, users could override the Valid
method in a
custom claim, for example to extend the validation with
application-specific claims. However, this was always very dangerous,
since once could easily disable the standard validation and signature
checking.
In order to avoid that, while still supporting the use-case, a new
ClaimsValidator
interface has been introduced. This
interface consists of the Validate() error
function. If the
validator sees, that a Claims
struct implements this
interface, the errors returned to the Validate
function
will be appended to the regular standard validation. It is not
possible to disable the standard validation anymore (even only by
accident).
Usage examples can be found in example_test.go, to build claims structs like the following.
// MyCustomClaims includes all registered claims, plus Foo.
type MyCustomClaims struct {
string `json:"foo"`
Foo .RegisteredClaims
jwt}
// Validate can be used to execute additional application-specific claims
// validation.
func (m MyCustomClaims) Validate() error {
if m.Foo != "bar" {
return errors.New("must be foobar")
}
return nil
}
Changes to the
Token
and Parser
struct
The previously global functions DecodeSegment
and
EncodeSegment
were moved to the Parser
and
Token
struct respectively. This will allow us in the future
to configure the behavior of these two based on options supplied on the
parser or the token (creation). This also removes two previously global
variables and moves them to parser options
WithStrictDecoding
and WithPaddingAllowed
.
In order to do that, we had to adjust the way signing methods work.
Previously they were given a base64 encoded signature in
Verify
and were expected to return a base64 encoded version
of the signature in Sign
, both as a string
.
However, this made it necessary to have DecodeSegment
and
EncodeSegment
global and was a less than perfect design
because we were repeating encoding/decoding steps for all signing
methods. Now, Sign
and Verify
operate on a
decoded signature as a []byte
, which feels more natural for
a cryptographic operation anyway. Lastly, Parse
and
SignedString
take care of the final encoding/decoding
part.
In addition to that, we also changed the Signature
field
on Token
from a string
to []byte
and this is also now populated with the decoded form. This is also more
consistent, because the other parts of the JWT, mainly
Header
and Claims
were already stored in
decoded form in Token
. Only the signature was stored in
base64 encoded form, which was redundant with the information in the
Raw
field, which contains the complete token as base64.
type Token struct {
string // Raw contains the raw token
Raw // Method is the signing method used or to be used
Method SigningMethod map[string]interface{} // Header is the first segment of the token in decoded form
Header // Claims is the second segment of the token in decoded form
Claims Claims []byte // Signature is the third segment of the token in decoded form
Signature bool // Valid specifies if the token is valid
Valid }
Most (if not all) of these changes should not impact the normal usage
of this library. Only users directly accessing the
Signature
field as well as developers of custom signing
methods should be affected.
Migration Guide (v4.0.0)
Starting from v4.0.0, the import path will be:
"github.com/golang-jwt/jwt/v4"
The /v4
version will be backwards compatible with
existing v3.x.y
tags in this repo, as well as
github.com/dgrijalva/jwt-go
. For most users this should be
a drop-in replacement, if you’re having troubles migrating, please open
an issue.
You can replace all occurrences of
github.com/dgrijalva/jwt-go
or
github.com/golang-jwt/jwt
with
github.com/golang-jwt/jwt/v4
, either manually or by using
tools such as sed
or gofmt
.
And then you’d typically run:
go get github.com/golang-jwt/jwt/v4
go mod tidy
Older releases (before v3.2.0)
The original migration guide for older releases can be found at https://github.com/dgrijalva/jwt-go/blob/master/MIGRATION_GUIDE.md.