csjwt

package
v0.0.0-...-b553abb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 31, 2019 License: Apache-2.0 Imports: 25 Imported by: 0

README

CoreStore optimized version

  • no empty interfaces
  • refactored code
  • higher performance
  • TODO(CS) update this readme for the code examples which are all ...

A go (or 'golang' for search engine friendliness) implementation of JSON Web Tokens

Build Status

NOTICE: A vulnerability in JWT was recently published. As this library doesn't force users to validate the alg is what they expected, it's possible your usage is effected. There will be an update soon to remedy this, and it will likey require backwards-incompatible changes to the API. In the short term, please make sure your implementation verifies the alg is what you expect.

What the heck is a JWT?

In short, it's a signed JSON object that does something useful (for example, authentication). It's commonly used for Bearer tokens in Oauth 2. A token is made of three parts, separated by .'s. The first two parts are JSON objects, that have been base64url encoded. The last part is the signature, encoded the same way.

The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used.

The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to the RFC for information about reserved keys and the proper way to add your own.

What's in the box?

This library supports the parsing and verification as well as the generation and signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own.

Parse and Verify

Parsing and verifying tokens is pretty straight forward. You pass in the token and a function for looking up the key. This is done as a callback since you may need to parse the token to find out what signing method and key was used.

	token, err := csjwt.Parse(myToken, func(token *csjwt.Token) (interface{}, error) {
		// Don't forget to validate the alg is what you expect:
		if _, ok := token.Method.(*csjwt.SigningMethodRSA); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		return myLookupKey(token.Header["kid"]), nil
	})

	if err == nil && token.Valid {
		deliverGoodness("!")
	} else {
		deliverUtterRejection(":(")
	}

Create a token

	// Create the token
	token := csjwt.NewWithClaims(csjwt.SigningMethodHS256, csjwt.MapClaims{
		"foo": "bar",
		"exp": time.Now().Add(time.Hour * 72).Unix(),
	})
	// Sign and get the complete encoded token as a string
	tokenString, err := token.SignedString(mySigningKey)

Extensions

This library publishes all the necessary components for adding your own signing methods. Simply implement the SigningMethod interface and register a factory method using RegisterSigningMethod.

Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go

Project Status & Versioning

This library is considered production ready. Feedback and feature requests are appreciated. The API should be considered stable. There should be very few backwards-incompatible changes outside of major version updates (and only with good reason).

This project uses Semantic Versioning 2.0.0. Accepted pull requests will land on master. Periodically, versions will be tagged from master. You can find all the releases on the project releases page.

While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users. You may want to use this alternative package include: gopkg.in/dgrijalva/jwt-go.v2. It will do the right thing WRT semantic versioning.

Migration Guide from v2 -> v3

Added the ability to supply a typed object for the claims section of the token.

Unfortunately this requires a breaking change. A few new methods were added to support this, and the old default of map[string]interface{} was changed to csjwt.MapClaims.

The old example for creating a token looked like this..

	token := csjwt.New(csjwt.SigningMethodHS256)
	token.Claims["foo"] = "bar"
	token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()

is now directly mapped to...

	token := csjwt.New(csjwt.SigningMethodHS256)
	claims := token.Claims.(csjwt.MapClaims)
	claims["foo"] = "bar"
	claims["exp"] = time.Now().Add(time.Hour * 72).Unix()

However, we added a helper csjwt.NewWithClaims which accepts a claims object.

Any type can now be used as the claim object for inside a token so long as it implements the interface csjwt.Claims.

So, we added an additional claim type csjwt.StandardClaims was added. This is intended to be used as a base for creating your own types from, and includes a few helper functions for verifying the claims defined here.

	claims := csjwt.StandardClaims{
		Audience: "myapi"
		ExpiresAt: time.Now().Add(time.Hour * 72).Unix(),
	}
	token := csjwt.NewWithClaims(csjwt.SigningMethodHS256, claims)

On the other end of usage all of the csjwt.Parse and friends got a WithClaims suffix added to them.

	token, err := csjwt.Parse(token, keyFunc)
	claims := token.Claims.(csjwt.MapClaim)
	//like you used to..
	claims["foo"]
	claims["bar"]

New method usage:

	token, err := csjwt.ParseWithClaims(token, keyFunc, &csjwt.StandardClaims{})
	claims := token.Claims.(csjwt.StandardClaims)
	fmt.Println(claims.IssuedAt)

Usage Tips

Signing vs Encryption

A token is simply a JSON object that is signed by its author. this tells you exactly two things about the data:

  • The author of the token was in the possession of the signing secret
  • The data has not been modified since it was signed

It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, JWE, that provides this functionality. JWE is currently outside the scope of this library.

Choosing a Signing Method

There are several signing methods available, and you should probably take the time to learn about the various options before choosing one. The principal design decision is most likely going to be symmetric vs asymmetric.

Symmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any []byte can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation.

Asymmetric signing methods, such as RSA, use different keys for signing and verifying tokens. This makes it possible to produce tokens with a private key, and allow any consumer to access the public key for verification.

JWT and OAuth

It's worth mentioning that OAuth and JWT are not the same thing. A JWT token is simply a signed JSON object. It can be used anywhere such a thing is useful. There is some confusion, though, as JWT is the most common type of bearer token used in OAuth2 authentication.

Without going too far down the rabbit hole, here's a description of the interaction of these technologies:

  • OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth.
  • OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that should only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token.
  • Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL.

More

Documentation can be found on godoc.org.

License

The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. For a more http centric example, see this gist.

Copyright (c) 2012 Dave Grijalva

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Documentation

Overview

Package csjwt handles JSON web tokens.

See README.md for more info. http://self-issued.info/docs/draft-jones-json-web-token.html

Further reading: https://float-middle.com/json-web-tokens-jwt-vs-sessions/ and http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/

https://news.ycombinator.com/item?id=11929267 => For people using JWT as a substitute for stateful sessions, how do you handle renewal (or revocation)?

https://news.ycombinator.com/item?id=14290114 => Things to Use Instead of JSON Web Tokens (inburke.com) TL;DR: Refactor the library and strip out RSA/ECDSA/encoding/decoding into its own sub-packages.

A new discussion: https://news.ycombinator.com/item?id=13865459 JSON Web Tokens should be avoided (paragonie.com)

Headless JWT mode: https://dev.to/neilmadden/7-best-practices-for-json-web-tokens

TODO: Investigate security bugs: http://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html Critical Vulnerability Uncovered in JSON Encryption. Executive Summary: If you are using go-jose, node-jose, jose2go, Nimbus JOSE+JWT or jose4 with ECDH-ES please update to the latest version. RFC 7516 aka JSON Web Encryption (JWE) Invalid Curve Attack. This can allow an attacker to recover the secret key of a party using JWE with Key Agreement with Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES), where the sender could extract receiver’s private key.

https://news.ycombinator.com/item?id=14727252 => https://github.com/shieldfy/API-Security-Checklist

https://dadario.com.br/revoking-json-web-tokens/

TODO(CyS) move RSA and ECDSA into its own subpackage ...

TODO(CyS) Consider PAST (Platform-Agnostic Security Tokens) https://news.ycombinator.com/item?id=16070394 https://github.com/paragonie/past

Index

Constants

View Source
const (
	ES256      = `ES256`
	ES384      = `ES384`
	ES512      = `ES512`
	HS256      = `HS256`
	HS384      = `HS384`
	HS512      = `HS512`
	PS256      = `PS256`
	PS384      = `PS384`
	PS512      = `PS512`
	RS256      = `RS256`
	RS384      = `RS384`
	RS512      = `RS512`
	ES         = `ES`
	HS         = `HS`
	PS         = `PS`
	RS         = `RS`
	Blake2b256 = `blk2b256`
	Blake2b512 = `blk2b512`
)

All available algorithms which are supported by this package.

View Source
const ContentTypeJWT = `JWT`

ContentTypeJWT defines the content type of a token. At the moment only JWT is supported. JWE may be added in the future JSON Web Encryption (JWE). https://tools.ietf.org/html/rfc7519

View Source
const HTTPFormInputName = `access_token`

HTTPFormInputName default name for the HTML form field name

View Source
const HTTPHeaderAuthorization = `Authorization`

HTTPHeaderAuthorization identifies the bearer token in this header key

View Source
const PrivateKeyBits = 2048

PrivateKeyBits used when auto generating a private key

Variables

View Source
var TimeFunc = time.Now

TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time). You can override it to use another time value. This is useful for testing or if your server uses a different time zone than your tokens.

Functions

func DecodeSegment

func DecodeSegment(seg []byte) ([]byte, error)

DecodeSegment decodes JWT specific base64url encoding with padding stripped. Returns a new byte slice. Error behaviour: NotValid.

func EncodeSegment

func EncodeSegment(seg []byte) []byte

EncodeSegment encodes JWT specific base64url encoding with padding stripped. Returns a new byte slice.

func MergeClaims

func MergeClaims(dst Claimer, srcs ...Claimer) error

MergeClaims merges the sources Claimers into the destination claimer existing token claims and overwrites existing entries. Destination Claimer must be a pointer. Error behaviour: NotSupported

func NewGobEncoding

func NewGobEncoding(primeObjects ...interface{}) *gobEncoding

NewGobEncoding creates a new primed gob Encoder/Decoder. Newly created Encoder/Decoder will Encode/Decode the passed sample structs without actually writing/reading from their respective Writer/Readers. This is useful for gob which encodes/decodes extra type information whenever it sees a new type. Pass sample values for primeObjects you plan on Encoding/Decoding to this method in order to avoid the storage overhead of encoding their type information for every NewEncoder/NewDecoder. Make sure you use gob.Register() for every type you plan to use otherwise there will be errors. Setting the primeObjects causes a priming of the encoder and decoder for each type. This function panics if the types, used for priming, can neither be encoded nor decoded.

func Parse

func Parse(dst *Token, rawToken []byte, keyFunc Keyfunc) error

Parse parses a rawToken into the destination token and may return an error. You must make sure to set the correct expected headers and claims in the destination Token. The Header and Claims field in the template token must be a pointer, as the destination Token itself.

Default configuration with defined CookieName of constant HTTPFormInputName, defined FormInputNam with value of constant HTTPFormInputName and supported Signers of HS256, HS384 and HS512.

func ParseFromRequest

func ParseFromRequest(dst *Token, keyFunc Keyfunc, req *http.Request) error

ParseFromRequest same as Parse but extracts the token from a request. First it searches for the token bearer in the header HTTPHeaderAuthorization. If not found, the cookie gets parsed and if not found then the request POST form gets parsed.

Default configuration with defined CookieName of constant HTTPFormInputName, defined FormInputNam with value of constant HTTPFormInputName and supported Signers of HS256, HS384 and HS512.

func SplitForVerify

func SplitForVerify(rawToken []byte) (signingString, signature []byte, err error)

SplitForVerify splits the token into two parts: the payload and the signature. An error gets returned if the number of dots don't match with the JWT standard.

Types

type Claimer

type Claimer interface {
	// Valid method that determines if the token is invalid for any supported reason.
	// Returns nil on success. Error behaviour: NotValid
	Valid() error
	// Expires declares when a token expires. A duration smaller or equal
	// to zero means that the token has already expired.
	// Useful when adding a token to a blacklist.
	Expires() time.Duration
	// Set sets a value to the claim and may overwrite existing values
	Set(key string, value interface{}) error
	// Get retrieves a value from the claim.
	Get(key string) (value interface{}, err error)
	// Keys returns a list of all available keys
	Keys() []string
}

Claimer for a type to be a Claims object

type Deserializer

type Deserializer interface {
	Deserialize(src []byte, dst interface{}) error
}

Deserializer provides an interface for providing custom deserializers. Also known as unserialize ;-)

type Head struct {
	// Alg (algorithm) header parameter identifies the cryptographic algorithm
	// used to secure the JWT. A list of reserved alg values is in Table 4. The
	// processing of the "alg" (algorithm) header parameter, if present,
	// requires that the value of the "alg" header parameter MUST be one that is
	// both supported and for which there exists a key for use with that
	// algorithm associated with the issuer of the JWT. This header parameter is
	// REQUIRED.
	Algorithm string `json:"alg,omitempty"`
	// Typ (type) header parameter is used to declare that this data structure
	// is a JWT. If a "typ" parameter is present, it is RECOMMENDED that its
	// value be "JWT". This header parameter is OPTIONAL.
	Type string `json:"typ,omitempty"`
}

Head minimum default header. To extend this header please use the struct jwtclaim.HeadSegments

func NewHead

func NewHead(alg ...string) *Head

NewHead creates a new minimum default header. Arguments alg can be optionally applied one time to define an algorithm but in all cases the algorithm gets set by the signing method. For test cases you can pass an algorithm argument. To extend this header please use the struct jwtclaim.HeadSegments

func (*Head) Alg

func (s *Head) Alg() string

Alg returns the underlying algorithm.

func (*Head) Get

func (s *Head) Get(key string) (string, error)

Get returns a value or nil or an error. Key must be one of the constants Header*. Error behaviour: NotSupported

func (*Head) GoString

func (s *Head) GoString() string

GoString prints the Go representation of the Head.

func (*Head) Set

func (s *Head) Set(key, value string) error

Set sets a value. Key must be one of the constants Header*. Error behaviour: NotSupported

func (*Head) String

func (s *Head) String() string

String prints the Go representation of the Head.

func (*Head) Typ

func (s *Head) Typ() string

Typ returns the token type.

type Header interface {
	// Alg returns the name of the underlying algorithm
	Alg() string
	// Typ identifies the type of the JSON web token
	Typ() string
	// Set error behaviour must be NotSupported
	Set(key, value string) error
	// Get error behaviour must be NotSupported
	Get(key string) (value string, err error)
}

Header defines the contract for a type to act like a header. It must be able to marshal and unmarshal itself. The members of the JSON object represented by the Decoded JWT Header Segment describe the signature applied to the JWT Header Segment and the JWT Payload Segment and optionally additional properties of the JWT. Implementations MUST understand the entire contents of the header; otherwise, the JWT MUST be rejected for processing.

type JSONEncoding

type JSONEncoding struct{}

JSONEncoding default JSON de- & serializer with base64 support

func (JSONEncoding) Deserialize

func (jp JSONEncoding) Deserialize(src []byte, dst interface{}) error

Deserialize decodes a value using encoding/json.

func (JSONEncoding) Serialize

func (jp JSONEncoding) Serialize(src interface{}) ([]byte, error)

Serialize encodes a value using encoding/json.

type Key

type Key struct {
	Error error
	// contains filtered or unexported fields
}

Key defines a container for the HMAC password, RSA and ECDSA public and private keys. The Error fields gets filled out when loading/parsing the keys.

func WithECPrivateKey

func WithECPrivateKey(privateKey *ecdsa.PrivateKey) (k Key)

WithECPrivateKey sets the ECDSA private key. Public key will be derived from the private key.

func WithECPrivateKeyFromFile

func WithECPrivateKeyFromFile(pathToFile string, password ...[]byte) (k Key)

WithECPrivateKeyFromFile parses file PEM encoded Elliptic Curve Private Key Structure. Public key will be derived from the private key. Provide a password as a second argument when the private key is encrypted. Public key will be derived from the private key.

func WithECPrivateKeyFromPEM

func WithECPrivateKeyFromPEM(privateKey []byte, password ...[]byte) (k Key)

WithECPrivateKeyFromPEM parses PEM encoded Elliptic Curve Private Key Structure. Provide a password as a second argument when the private key is encrypted. Public key will be derived from the private key.

func WithECPublicKey

func WithECPublicKey(publicKey *ecdsa.PublicKey) (k Key)

WithECPublicKey sets the ECDSA public key

func WithECPublicKeyFromFile

func WithECPublicKeyFromFile(pathToFile string) (k Key)

WithECPublicKeyFromFile parses a file PEM encoded Elliptic Curve Public Key Structure.

func WithECPublicKeyFromPEM

func WithECPublicKeyFromPEM(publicKey []byte) (k Key)

WithECPublicKeyFromPEM parses PEM encoded Elliptic Curve Public Key Structure

func WithPassword

func WithPassword(password []byte) Key

WithPassword uses the byte slice as the password for the HMAC-SHA signing method.

func WithPasswordFromFile

func WithPasswordFromFile(pathToFile string) Key

WithPasswordFromFile loads the content of a file and uses that content as the password for the HMAC-SHA signing method.

func WithPasswordRandom

func WithPasswordRandom() Key

WithPasswordRandom creates cryptographically secure random password which you cannot obtain. Whenever you restart your app with a random password, all HMAC-SHA tokens get invalided.

func WithRSAGenerated

func WithRSAGenerated() (k Key)

WithRSAGenerated creates an in-memory private key to be used for signing and verifying. Bit size see constant: PrivateKeyBits Public key will be derived from the private key.

func WithRSAPrivateKey

func WithRSAPrivateKey(privateKey *rsa.PrivateKey) (k Key)

WithRSAPrivateKey sets the private key. Public key will be derived from the private key.

func WithRSAPrivateKeyFromFile

func WithRSAPrivateKeyFromFile(pathToFile string, password ...[]byte) (k Key)

WithRSAPrivateKeyFromFile parses PEM encoded PKCS1 or PKCS8 private key found in a file. Provide a password as a second argument when the private key is encrypted. Public key will be derived from the private key.

func WithRSAPrivateKeyFromPEM

func WithRSAPrivateKeyFromPEM(privateKey []byte, password ...[]byte) (k Key)

WithRSAPrivateKeyFromPEM parses PEM encoded PKCS1 or PKCS8 private key. Provide a password as a second argument when the private key is encrypted. Public key will be derived from the private key.

func WithRSAPublicKey

func WithRSAPublicKey(publicKey *rsa.PublicKey) (k Key)

WithRSAPublicKey sets the public key

func WithRSAPublicKeyFromFile

func WithRSAPublicKeyFromFile(pathToFile string) (k Key)

WithRSAPublicKeyFromFile parses PEM encoded PKCS1 or PKCS8 public key found in a file.

func WithRSAPublicKeyFromPEM

func WithRSAPublicKeyFromPEM(publicKey []byte) (k Key)

WithRSAPublicKeyFromPEM parses PEM encoded PKCS1 or PKCS8 public key

func (Key) Algorithm

func (k Key) Algorithm() (a string)

Algorithm returns the supported algorithm but not the bit size. Returns 0 on error, or one of the constants: ES, HS or RS.

func (Key) GoString

func (k Key) GoString() string

GoString protects keys and enforces privacy.

func (Key) IsEmpty

func (k Key) IsEmpty() bool

IsEmpty returns true when no field has been used in the Key struct. Error is excluded from the check.

func (Key) String

func (k Key) String() string

String protects keys and enforces privacy.

type Keyfunc

type Keyfunc func(*Token) (Key, error)

Keyfunc used by Parse methods, this callback function supplies the key for verification. The function receives the parsed, but unverified Token. This allows you to use properties in the Header of the token (such as `kid`) to identify which key to use.

func NewKeyFunc

func NewKeyFunc(s Signer, key Key) Keyfunc

NewKeyFunc creates a new function for token validation and specific key returning. This function checks only if the token algorithm matches the algorithm of the Signer. csjwt.NewVerification() allows you to add also Signers as arguments to check for the correct signatures, but this function is more specific and returns the correct key to check the signature.

type Serializer

type Serializer interface {
	Serialize(src interface{}) ([]byte, error)
}

Serializer provides an interface for providing custom serializers.

type Signer

type Signer interface {
	// Verify returns nil if signature is valid
	Verify(signingString, signature []byte, key Key) error
	// Sign returns encoded signature or error
	Sign(signingString []byte, key Key) ([]byte, error)
	// Alg returns the alg identifier for this method (example: 'HS256')
	Alg() string
}

Signer interface to add new methods for signing or verifying tokens.

func MustSigningMethodFactory

func MustSigningMethodFactory(alg string) Signer

MustSigningMethodFactory same as SigningMethodFactory but panics on error. You should only use the Must* functions during init process or testing.

func NewSigningMethodBlake2b256

func NewSigningMethodBlake2b256(key Key) (Signer, error)

NewSigningMethodBlake2b256 creates a new HMAC-Blake2b hash with a preset password and 32-byte checksum. Blake2b uses SIMD optimizations via ASM code. https://blake2.net/

func NewSigningMethodBlake2b512

func NewSigningMethodBlake2b512(key Key) (Signer, error)

NewSigningMethodBlake2b512 creates a new HMAC-Blake2b hash with a preset password and 64-byte checksum. Blake2b uses SIMD optimizations via ASM code. https://blake2.net/

func NewSigningMethodHS256Fast

func NewSigningMethodHS256Fast(key Key) (Signer, error)

NewSigningMethodHS256Fast creates a new HMAC-SHA hash with a preset password and does not register it globally. It uses internally a sync.Pool hashes.

func NewSigningMethodHS384Fast

func NewSigningMethodHS384Fast(key Key) (Signer, error)

NewSigningMethodHS384Fast creates a new HMAC-SHA hash with a preset password and does not register it globally. It uses internally a sync.Pool hashes.

func NewSigningMethodHS512Fast

func NewSigningMethodHS512Fast(key Key) (Signer, error)

NewSigningMethodHS512Fast creates a new HMAC-SHA hash with a preset password and does not register it globally. It uses internally a sync.Pool hashes.

func SigningMethodFactory

func SigningMethodFactory(alg string) (s Signer, err error)

SigningMethodFactory creates a new signing method by an algorithm. Supported algorithms are: ES, HS, PS and RS, all within 256-512 and they do not need a symmetric key. Returns an error for an unknown signing method.

type SignerSlice

type SignerSlice []Signer

SignerSlice helper type

func (SignerSlice) Contains

func (ms SignerSlice) Contains(alg string) bool

Contains checks if the algorithm has already been added

func (SignerSlice) String

func (ms SignerSlice) String() string

String returns a list of algorithms, comma separated

type SigningMethodECDSA

type SigningMethodECDSA struct {
	Name      string
	Hash      crypto.Hash
	KeySize   int
	CurveBits int
}

SigningMethodECDSA implements the ECDSA family of signing methods signing methods.

func NewSigningMethodES256

func NewSigningMethodES256() *SigningMethodECDSA

NewSigningMethodES256 creates a new 256bit ECDSA SHA instance and registers it.

func NewSigningMethodES384

func NewSigningMethodES384() *SigningMethodECDSA

NewSigningMethodES384 creates a new 384bit ECDSA SHA instance and registers it.

func NewSigningMethodES512

func NewSigningMethodES512() *SigningMethodECDSA

NewSigningMethodES512 creates a new 512bit ECDSA SHA instance and registers it.

func (*SigningMethodECDSA) Alg

func (m *SigningMethodECDSA) Alg() string

Alg returns the name of the underlying algorithm.

func (*SigningMethodECDSA) Sign

func (m *SigningMethodECDSA) Sign(signingString []byte, key Key) ([]byte, error)

Sign implements the Sign method from SigningMethod. For the key you can use any of the WithECPrivateKey*() functions. Error behaviour: Empty, NotImplemented, WriteFailed, NotValid.

func (*SigningMethodECDSA) Verify

func (m *SigningMethodECDSA) Verify(signingString, signature []byte, key Key) error

Verify implements the Verify method from SigningMethod interface. For the key you can use any of the WithEC*Key*() functions Error behaviour: Empty, NotImplemented, WriteFailed, NotValid.

type SigningMethodHMAC

type SigningMethodHMAC struct {
	Name string
	Hash crypto.Hash
}

SigningMethodHMAC implements the HMAC-SHA family of signing methods signing methods.

func NewSigningMethodHS256

func NewSigningMethodHS256() *SigningMethodHMAC

NewSigningMethodHS256 creates a new 256bit HMAC SHA instance and registers it.

func NewSigningMethodHS384

func NewSigningMethodHS384() *SigningMethodHMAC

NewSigningMethodHS384 creates a new 384bit HMAC SHA instance and registers it.

func NewSigningMethodHS512

func NewSigningMethodHS512() *SigningMethodHMAC

NewSigningMethodHS512 creates a new 512bit HMAC SHA instance and registers it.

func (*SigningMethodHMAC) Alg

func (m *SigningMethodHMAC) Alg() string

Alg returns the used algorithm.

func (*SigningMethodHMAC) Sign

func (m *SigningMethodHMAC) Sign(signingString []byte, key Key) ([]byte, error)

Sign implements the Sign method from SigningMethod interface. For the key you can use any of the WithPassword*() functions. Error behaviour: Empty, NotImplemented, WriteFailed

func (*SigningMethodHMAC) Verify

func (m *SigningMethodHMAC) Verify(signingString, signature []byte, key Key) error

Verify the signature of HSXXX tokens. Returns nil if the signature is valid. For the key you can use any of the WithPassword*() functions. Error behaviour: Empty, NotImplemented, WriteFailed, NotValid.

type SigningMethodHSFast

type SigningMethodHSFast struct {
	Name string
	// contains filtered or unexported fields
}

SigningMethodHSFast implements the HMAC-SHA family of pre-warmed signing methods. Less allocations, bytes and a little bit faster but maybe the underlying mutex can become the bottleneck.

func (*SigningMethodHSFast) Alg

func (m *SigningMethodHSFast) Alg() string

func (*SigningMethodHSFast) Sign

func (m *SigningMethodHSFast) Sign(signingString []byte, _ Key) ([]byte, error)

Sign implements the Sign method from SigningMethod interface. Error behaviour: WriteFailed

func (*SigningMethodHSFast) Verify

func (m *SigningMethodHSFast) Verify(signingString, signature []byte, _ Key) error

Verify the signature of HSXXX tokens. Returns nil if the signature is valid. Error behaviour: NotImplemented, WriteFailed, NotValid

type SigningMethodRSA

type SigningMethodRSA struct {
	Name string
	Hash crypto.Hash
}

SigningMethodRSA implements the RSA family of signing methods signing methods

func NewSigningMethodRS256

func NewSigningMethodRS256() *SigningMethodRSA

NewSigningMethodRS256 creates a new 256bit RSA SHA instance and registers it.

func NewSigningMethodRS384

func NewSigningMethodRS384() *SigningMethodRSA

NewSigningMethodRS384 creates a new 384bit RSA SHA instance and registers it.

func NewSigningMethodRS512

func NewSigningMethodRS512() *SigningMethodRSA

NewSigningMethodRS512 creates a new 512bit RSA SHA instance and registers it.

func (*SigningMethodRSA) Alg

func (m *SigningMethodRSA) Alg() string

func (*SigningMethodRSA) Sign

func (m *SigningMethodRSA) Sign(signingString []byte, key Key) ([]byte, error)

Sign implements the Sign method from SigningMethod interface. For the key you can use any of the WithRSAPrivateKey*() functions. Error behaviour: Empty, NotImplemented, WriteFailed, NotValid.

func (*SigningMethodRSA) Verify

func (m *SigningMethodRSA) Verify(signingString, signature []byte, key Key) error

Verify implements the Verify method from SigningMethod interface. For the key you can use any of the WithRSA*Key*() functions. Error behaviour: Empty, NotImplemented, WriteFailed, NotValid

type SigningMethodRSAPSS

type SigningMethodRSAPSS struct {
	SigningMethodRSA
	Options rsa.PSSOptions
}

SigningMethodRSAPSS implements the RSAPSS family of signing methods signing methods.

func NewSigningMethodPS256

func NewSigningMethodPS256() *SigningMethodRSAPSS

NewSigningMethodPS256 creates a new 256bit RSAPSS SHA instance and registers it.

func NewSigningMethodPS384

func NewSigningMethodPS384() *SigningMethodRSAPSS

NewSigningMethodPS384 creates a new 384bit RSAPSS SHA instance and registers it.

func NewSigningMethodPS512

func NewSigningMethodPS512() *SigningMethodRSAPSS

NewSigningMethodPS512 creates a new 512bit RSAPSS SHA instance and registers it.

func (*SigningMethodRSAPSS) Sign

func (m *SigningMethodRSAPSS) Sign(signingString []byte, key Key) ([]byte, error)

Sign implements the Sign method from SigningMethod interface. For the key you can use any of the WithRSAPrivateKey*() functions. Error behaviour: Empty, NotImplemented, WriteFailed, NotValid.

func (*SigningMethodRSAPSS) Verify

func (m *SigningMethodRSAPSS) Verify(signingString, signature []byte, key Key) error

Verify implements the Verify method from SigningMethod interface. For the key you can use any of the WithRSA*Key*() functions. Error behaviour: Empty, NotImplemented, WriteFailed, NotValid

type Token

type Token struct {
	Raw       []byte  // The raw token.  Populated when you Parse a token
	Header    Header  // The first segment of the token
	Claims    Claimer // The second segment of the token
	Signature []byte  // The third segment of the token.  Populated when you Parse a token
	Valid     bool    // Is the token valid?  Populated when you Parse/Verify a token
	Serializer
}

Token represents a JWT Token. Different fields will be used depending on whether you're creating or parsing/verifying a token.

func NewToken

func NewToken(c Claimer) Token

NewToken creates a new Token and presets the header to typ = JWT. A new token has not yet an assigned algorithm. The underlying default template header consists of a two field struct for the minimum requirements. If you need more header fields consider using a map or the jwtclaim.HeadSegments type. Default header from function NewHead().

func (Token) Alg

func (t Token) Alg() string

Alg returns the assigned algorithm to this token. Can return an empty string.

func (Token) MarshalLog

func (t Token) MarshalLog(kv log.KeyValuer) error

MarshalLog marshals the token into an unsigned log.Field. It uses the function SigningString().

func (Token) SignedString

func (t Token) SignedString(method Signer, key Key) ([]byte, error)

SignedString gets the complete, signed token. Sets the header alg to the provided Signer.Alg() value. Returns a byte slice, save for further processing. This functions allows to sign a token with different signing methods.

func (Token) SigningString

func (t Token) SigningString() (buf bytes.Buffer, err error)

SigningString generates the signing string. This is the most expensive part of the whole deal. Unless you need this for something special, just go straight for the SignedString. Returns a buffer which can be used for further modifications.

type Verification

type Verification struct {
	// FormInputName defines the name of the HTML form input type in which the
	// token has been stored. If empty, the form the gets ignored.
	FormInputName string
	// CookieName defines the name of the cookie where the token has been stored. If
	// empty, cookie parsing gets ignored.
	CookieName string
	// Methods for verifying and signing a token
	Methods SignerSlice

	// Decoder interface to pass in a custom decoder parser. Can be nil, falls
	// back to JSON.
	Deserializer
}

Verification allows to parse and verify a token with custom options.

func NewVerification

func NewVerification(availableSigners ...Signer) *Verification

NewVerification creates new verification parser with the default signing method HS256, if availableSigners slice argument is empty. Nil arguments are forbidden.

func (*Verification) Parse

func (vf *Verification) Parse(dst *Token, rawToken []byte, keyFunc Keyfunc) error

Parse parses a rawToken into the destination token and may return an error. You must make sure to set the correct expected headers and claims in the template Token. The Header and Claims field in the destination token must be a pointer as the token itself. Error behaviour: Empty, NotFound, NotValid

func (*Verification) ParseFromRequest

func (vf *Verification) ParseFromRequest(dst *Token, keyFunc Keyfunc, req *http.Request) error

ParseFromRequest same as Parse but extracts the token from a request. First it searches for the token bearer in the header HTTPHeaderAuthorization. If not found the request POST form gets parsed and the FormInputName gets used to lookup the token value.

Directories

Path Synopsis
cmd
jwt
A useful example app.
A useful example app.
Package jwtclaim provides claim structs and maps for convenience.
Package jwtclaim provides claim structs and maps for convenience.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL