Documentation ¶
Index ¶
- Constants
- Variables
- func ParseJwtHeaders(jwtValue string) (map[string]interface{}, error)
- type CryptoKeyProperties
- type CryptoProperties
- type FileJwkStore
- func (s *FileJwkStore) LoadAll(_ context.Context, names ...string) ([]Jwk, error)
- func (s *FileJwkStore) LoadByKid(_ context.Context, kid string) (Jwk, error)
- func (s *FileJwkStore) LoadByName(_ context.Context, name string) (Jwk, error)
- func (s *FileJwkStore) Rotate(_ context.Context, name string) error
- type GenericJwk
- type GenericPrivateJwk
- type Jwk
- type JwkRotator
- type JwkStore
- type JwtDecoder
- type JwtEncoder
- type JwtProperties
- type KeyFormatType
- type PlaintextJwtDecoder
- type PrivateJwk
- type RemoteJwkConfig
- type RemoteJwkOptions
- type RemoteJwkStore
- type SignedJwtDecoder
- type SignedJwtEncoder
- type SigningOption
- type SigningOptions
- type SingleJwkStore
- type StaticJwkStore
- func (s *StaticJwkStore) LoadAll(_ context.Context, _ ...string) ([]Jwk, error)
- func (s *StaticJwkStore) LoadByKid(_ context.Context, kid string) (Jwk, error)
- func (s *StaticJwkStore) LoadByName(_ context.Context, _ string) (Jwk, error)
- func (s *StaticJwkStore) Rotate(_ context.Context, _ string) error
- type VerifyOption
- type VerifyOptions
Constants ¶
const ( JwtHeaderType = "typ" JwtHeaderAlgorithm = "alg" JwtHeaderKid = "kid" )
const ( JwkTypeEC = `EC` JwkTypeRSA = `RSA` JwkTypeOctet = `oct` JwkTypeEdDSA = `OKP` )
const CryptoKeysPropertiesPrefix = "security"
Variables ¶
var ( SymmetricSigningMethods = []jwt.SigningMethod{ jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512, } AsymmetricSigningMethods = []jwt.SigningMethod{ jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512, jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512, jwt.SigningMethodPS256, jwt.SigningMethodPS384, jwt.SigningMethodPS512, jwt.SigningMethodEdDSA, } SupportedSigningMethods = append(AsymmetricSigningMethods, SymmetricSigningMethods...) )
Functions ¶
func ParseJwtHeaders ¶
ParseJwtHeaders extract JWT's headers without verifying the token
Types ¶
type CryptoKeyProperties ¶
type CryptoKeyProperties struct { Id string `json:"id"` KeyFormat string `json:"format"` Location string `json:"file"` Password string `json:"password"` }
func (CryptoKeyProperties) Format ¶
func (p CryptoKeyProperties) Format() KeyFormatType
type CryptoProperties ¶
type CryptoProperties struct { Keys map[string]CryptoKeyProperties `json:"keys"` Jwt JwtProperties `json:"jwt"` }
func BindCryptoProperties ¶
func BindCryptoProperties(ctx *bootstrap.ApplicationContext) CryptoProperties
BindCryptoProperties create and bind CryptoProperties, with a optional prefix
func NewCryptoProperties ¶
func NewCryptoProperties() *CryptoProperties
NewCryptoProperties create a CryptoProperties with default values
type FileJwkStore ¶
type FileJwkStore struct {
// contains filtered or unexported fields
}
FileJwkStore implements JwkStore and JwkRotator This store uses load key files for public and private keys. File locations and "kids" are read from properties. And rotate between pre-defined keys The properties are structured as follows:
keys: my-key-name: id: my-key-id format: pem file: my-key-file.pem
Keys loaded under the same key name will all have the same name. The LoadByName method will load one of the keys. Which key will be loaded is determined by the current index for that name. The Rotate method will increment the index for that name. If the pem file contains one key, the key id will be the same as the key name.
If the pem file contains multiple keys, the following rules will be used to generate the key id:
If id property is provided, the actual key id will be the property id plus an integer suffix. If id property is not provided, the actual key id will be generated based on elements of the public key. The ID value will be consistent across restarts.
Supports PEM format. Supports: 1. PKCS8 unencrypted private key (rsa, ecdsa, ed25519) 2. traditional unencrypted private key and encrypted private key (rsa and ecdsa) 3. traditional public key (pkcs1 for rsa or pkix for rsa, PKIX for ecdsa and ed25519) 4. x509 certificate (rsa, ecdsa, ed25519) 5. HMAC key (using custom label "HMAC KEY", i.e. -----BEGIN HMAC KEY-----)
Note that if HMAC is used, the application must be responsible for securing the jwks endpoint, or encrypt the jwks content. This is because HMAC keys are symmetric and should not be exposed to public. By default, the jwks endpoint is not secured.
func NewFileJwkStore ¶
func NewFileJwkStore(props CryptoProperties) *FileJwkStore
func (*FileJwkStore) LoadByName ¶
type GenericJwk ¶ added in v0.15.0
type GenericJwk struct {
// contains filtered or unexported fields
}
GenericJwk implements Jwk
func (*GenericJwk) Id ¶ added in v0.15.0
func (k *GenericJwk) Id() string
func (*GenericJwk) MarshalJSON ¶ added in v0.15.0
func (k *GenericJwk) MarshalJSON() ([]byte, error)
func (*GenericJwk) Name ¶ added in v0.15.0
func (k *GenericJwk) Name() string
func (*GenericJwk) Public ¶ added in v0.15.0
func (k *GenericJwk) Public() crypto.PublicKey
func (*GenericJwk) UnmarshalJSON ¶ added in v0.15.0
func (k *GenericJwk) UnmarshalJSON(data []byte) error
type GenericPrivateJwk ¶ added in v0.15.0
type GenericPrivateJwk struct { GenericJwk // contains filtered or unexported fields }
GenericPrivateJwk implements Jwk and PrivateJwk
func (*GenericPrivateJwk) Private ¶ added in v0.15.0
func (k *GenericPrivateJwk) Private() crypto.PrivateKey
type Jwk ¶
func NewJwk ¶ added in v0.15.0
NewJwk new Jwk with specified public key Supported public key types:
- *rsa.PublicKey
- *ecdsa.PublicKey
- ed25519.PublicKey
- []byte (MAC secret)
- any key implementing: interface{ Equal(x crypto.PublicKey) bool }
func ParseJwk ¶ added in v0.15.0
ParseJwk parse Jwk from JSON as specified in RFC 7517 and RFC 7518. Note: Private key information is ignored in the parsed Jwk. Supported public key types: - *rsa.PublicKey (kty = RSA) - *ecdsa.PublicKey (kty = EC) - ed25519.PublicKey (kty = OKP) - []byte (symmetric key, e.g. MAC secret) ((kty = oct)
See: RFC7517 https://datatracker.ietf.org/doc/html/rfc7517 See: RFC7518 https://datatracker.ietf.org/doc/html/rfc7518
type JwkRotator ¶
type JwkStore ¶
type JwkStore interface { // LoadByKid returns the JWK associated with given KID. // This method is usually used when decoding/verifiying JWT token LoadByKid(ctx context.Context, kid string) (Jwk, error) // LoadByName returns the JWK associated with given name. // The method might return different JWK for same name, if the store is also support rotation // This method is usually used when encoding/encrypt JWT token // Note: if the store does not support rotation (i.e. it doest not implement JwkRotator), // this store could use the name as the jwk id. Doing so would allow the encoder to not // add a "kid" header to the JWT token. This allows the use case where the JWT key is agreed upon by // both the encoder and decoder through an out-of-band mechanism without using "kid". // See the comment in SignedJwtEncoder.Encode for more details LoadByName(ctx context.Context, name string) (Jwk, error) // LoadAll return all JWK with given names. If name is not provided, all JWK is returned LoadAll(ctx context.Context, names ...string) ([]Jwk, error) }
type JwtDecoder ¶
type JwtEncoder ¶
type JwtProperties ¶
type JwtProperties struct {
KeyName string `json:"key-name"`
}
type PlaintextJwtDecoder ¶
type PlaintextJwtDecoder struct {
// contains filtered or unexported fields
}
PlaintextJwtDecoder implements JwtEncoder
func NewPlaintextJwtDecoder ¶
func NewPlaintextJwtDecoder() *PlaintextJwtDecoder
func (*PlaintextJwtDecoder) DecodeWithClaims ¶
func (dec *PlaintextJwtDecoder) DecodeWithClaims(_ context.Context, tokenString string, claims interface{}) (err error)
type PrivateJwk ¶
type PrivateJwk interface { Jwk Private() crypto.PrivateKey }
func NewPrivateJwk ¶ added in v0.15.0
func NewPrivateJwk(kid string, name string, privKey crypto.PrivateKey) PrivateJwk
NewPrivateJwk new PrivateJwk with specified private key Supported private key types:
- *rsa.PrivateKey
- *ecdsa.PrivateKey
- ed25519.PrivateKey
- []byte (MAC secret)
- any key implementing: interface{ Public() crypto.PublicKey Equal(x crypto.PrivateKey) bool }
type RemoteJwkConfig ¶ added in v0.15.0
type RemoteJwkConfig struct { // HttpClient the underlying http.Client to use. Default: http.DefaultClient HttpClient *http.Client // JwkSetURL the URL of JWKSet endpoint for getting all JWKs. Default: "http://localhost:8900/auth/v2/jwks" // e.g. http://localhost:8900/auth/v2/jwks JwkSetURL string // JwkBaseURL the base URL of the endpoint for getting JWK by kid (without tailing slash). The actual URL would be "JwkBaseURL/<kid>". // (Optional) When not set (empty string), the JwkSetURL is used. Default: "http://localhost:8900/auth/v2/jwks" // e.g. JwkBaseURL = "http://localhost:8900/auth/v2/jwks", actual URL is "http://localhost:8900/auth/v2/jwks/<kid>" JwkBaseURL string // JwkSetRequestFunc a function that create http.Request for JWKSet endpoint. When set, override JwkSetURL. // (Optional) When not set, JwkSetURL is used with GET method. JwkSetRequestFunc func(ctx context.Context) *http.Request // JwkRequestFunc a function that create http.Request for "get JWK by kid". When set, override JwkBaseURL. // (Optional) When not set, JwkBaseURL is used with GET method. If JwkBaseURL is not set either, JWKSet endpoint is used. JwkRequestFunc func(ctx context.Context, kid string) *http.Request // DisableCache disable internal caching. If the cache is disabled, the store would invoke an external HTTP transaction // everytime when any of store's method is called. Default: false DisableCache bool // TTL cache setting. TTL controls how long the HTTP result is kept in cache. TTL time.Duration // RetryBackoff cache setting. It controls how long to wait between failed HTTP retries. RetryBackoff time.Duration // Retry cache setting. It controls how many times the cache would retry for failed HTTP transaction. Retry int }
type RemoteJwkOptions ¶ added in v0.15.0
type RemoteJwkOptions func(cfg *RemoteJwkConfig)
type RemoteJwkStore ¶ added in v0.15.0
type RemoteJwkStore struct { RemoteJwkConfig // contains filtered or unexported fields }
RemoteJwkStore implements JwkStore and load JWK with public key from an external JWKSet endpoint. Important: Use RemoteJwkStore with JwtDecoder ONLY.
RemoteJwkStore is not capable of decrypt private key from JWK response
Note: LoadByName and LoadAll would treat Jwk's "name" as "kid". Because "name" is introduced for managing
key rotation, which is not applicable to JwtDecoder: JwtDecoder strictly use `kid` if present in header or default "name" (in such case, should be hard coded globally known "kid")
func NewRemoteJwkStore ¶ added in v0.15.0
func NewRemoteJwkStore(opts ...RemoteJwkOptions) *RemoteJwkStore
NewRemoteJwkStore creates a JwkStore that load JWK with public key from an external JWKSet endpoint. Note: Use RemoteJwkStore with JwtDecoder ONLY.
RemoteJwkStore is not capable of decrypt private key from JWK response.
See RemoteJwkStore for more details
func (*RemoteJwkStore) LoadByName ¶ added in v0.15.0
type SignedJwtDecoder ¶ added in v0.15.0
type SignedJwtDecoder struct {
// contains filtered or unexported fields
}
SignedJwtDecoder implements JwtEncoder
func NewSignedJwtDecoder ¶ added in v0.15.0
func NewSignedJwtDecoder(opts ...VerifyOptions) *SignedJwtDecoder
func (*SignedJwtDecoder) DecodeWithClaims ¶ added in v0.15.0
func (dec *SignedJwtDecoder) DecodeWithClaims(ctx context.Context, tokenString string, claims interface{}) (err error)
type SignedJwtEncoder ¶ added in v0.15.0
type SignedJwtEncoder struct {
// contains filtered or unexported fields
}
SignedJwtEncoder implements JwtEncoder. It encodes claims with crypto signature of choice. Encoder may return error if private key is not compatible with signing method
func NewSignedJwtEncoder ¶ added in v0.15.0
func NewSignedJwtEncoder(opts ...SigningOptions) *SignedJwtEncoder
NewSignedJwtEncoder create a JwtEncoder that sign JWT with provided method. Depending on the sign method, provided JwkStore should supply proper private keys. Note: When using HS algorithms, the HMAC secret is treated as both public and private key,
and it would be exposed via JWKS endpoint. It is service implementer's responsibility to protect the JWKS endpoint to prevent accidental leaking of HMAC secret.
type SigningOption ¶ added in v0.15.0
type SigningOptions ¶ added in v0.15.0
type SigningOptions func(opt *SigningOption)
func SignWithJwkStore ¶ added in v0.15.0
func SignWithJwkStore(store JwkStore, jwkName string) SigningOptions
SignWithJwkStore is a SigningOptions that set JwkStore and key name to use when signing
func SignWithMethod ¶ added in v0.15.0
func SignWithMethod(method jwt.SigningMethod) SigningOptions
SignWithMethod is SigningOptions that specify the method to use. When set to nil, the encoder would attempt to use the private key type to resolve signing method.
type SingleJwkStore ¶
type SingleJwkStore struct { Kid string SigningMethod jwt.SigningMethod // contains filtered or unexported fields }
SingleJwkStore implements JwkStore This store always returns single JWK if Kid matches, return error if not This store is majorly for testing
func NewSingleJwkStore ¶
func NewSingleJwkStore(kid string) *SingleJwkStore
NewSingleJwkStore Deprecated: Use NewSingleJwkStoreWithOptions
func NewSingleJwkStoreWithOptions ¶ added in v0.15.0
func NewSingleJwkStoreWithOptions(opts ...func(s *SingleJwkStore)) *SingleJwkStore
func (*SingleJwkStore) LazyInit ¶ added in v0.15.0
func (s *SingleJwkStore) LazyInit() (err error)
func (*SingleJwkStore) LoadByName ¶
type StaticJwkStore ¶
type StaticJwkStore struct { KIDs []string SigningMethod jwt.SigningMethod // contains filtered or unexported fields }
StaticJwkStore implements JwkStore and JwkRotator This store uses "kid" as seed to generate PrivateJwk. For same "kid" the returned key is same. this one is not thread safe
func NewStaticJwkStore ¶
func NewStaticJwkStore(kids ...string) *StaticJwkStore
NewStaticJwkStore Deprecated: Use NewStaticJwkStoreWithOptions
func NewStaticJwkStoreWithOptions ¶ added in v0.15.0
func NewStaticJwkStoreWithOptions(opts ...func(s *StaticJwkStore)) *StaticJwkStore
func (*StaticJwkStore) LoadByName ¶
type VerifyOption ¶ added in v0.15.0
type VerifyOptions ¶ added in v0.15.0
type VerifyOptions func(opt *VerifyOption)
func VerifyWithJwkStore ¶ added in v0.15.0
func VerifyWithJwkStore(store JwkStore, jwkName string) VerifyOptions
VerifyWithJwkStore is a VerifyOptions that set JwkStore and default key name to use when verifying. the provided key name is used as fallback if the to-be-verified JWT doesn't have "kid" in header
func VerifyWithMethods ¶ added in v0.15.0
func VerifyWithMethods(methods ...jwt.SigningMethod) VerifyOptions
VerifyWithMethods is a VerifyOptions that specify all allowed signing method ("alg" header). By default, it accepts all available signing methods except for plaintext JWT.