Documentation ¶
Overview ¶
Package security can be used to implement our bearer and hmac security of HTTP requests. Agents can use the HMACAuth to create HMAC secured HTTP requests. The serverside also uses this to pull out the user from the request.
A Dex is used to get a user from a request who is identified by a bearer token. We use a dex backend to load the keys from our service so we can verify the signature of the JWT token. It is up to the client to get a correct bearer token.
Index ¶
- Constants
- func AddUserToken(rq *http.Request, token string)
- func AddUserTokenToClientRequest(rq runtime.ClientRequest, token string)
- func CreateToken(signer jose.Signer, cl any, privateClaims ...any) (string, error)
- func CreateTokenAndKeys(cfg *TokenCfg) (token string, pubKey jose.JSONWebKey, privKey jose.JSONWebKey, err error)
- func CreateWebkeyPair(alg jose.SignatureAlgorithm, use string, keylenBits int) (jose.JSONWebKey, jose.JSONWebKey, error)
- func ExtractBearer(rq *http.Request) (string, error)
- func GenerateSigningKey(alg jose.SignatureAlgorithm, bits int) (crypto.PublicKey, crypto.PrivateKey, error)
- func GenerateTokenAndKeyServer(tc *TokenCfg, tokenProvider TokenProvider, opts ...KeyServerOption) (srv *httptest.Server, token string, err error)
- func MustCreateTokenAndKeys(cfg *TokenCfg) (token string, pubKey jose.JSONWebKey, privKey jose.JSONWebKey)
- func MustMakeSigner(alg jose.SignatureAlgorithm, k any) jose.Signer
- func ParseTokenClaimsUnvalidated(req *http.Request) (*jwt.Claims, error)
- func PutUserInContext(ctx context.Context, u *User) context.Context
- type Annotations
- type Claims
- type CredsOpt
- type Dex
- type GenericOIDC
- type GenericOIDCCfg
- type GenericOIDCClaims
- type GenericOIDCOption
- type GenericUserExtractorFn
- type HMACAuth
- func (hma *HMACAuth) AddAuth(rq *http.Request, t time.Time, body []byte)
- func (hma *HMACAuth) AddAuthToClientRequest(rq runtime.ClientRequest, t time.Time)
- func (hma *HMACAuth) AuthHeaders(method string, t time.Time) map[string]string
- func (hma *HMACAuth) User(rq *http.Request) (*User, error)
- func (hma *HMACAuth) UserFromRequestData(requestData RequestData) (*User, error)
- type HMACAuthOption
- type Issuer
- type IssuerConfig
- type IssuerListProvider
- type IssuerNotFound
- type KeyServerConfig
- type KeyServerOption
- type MultiIssuerCache
- type MultiIssuerUserGetterOption
- type Option
- type RequestData
- type RequestDataGetter
- type ResourceAccess
- type TokenCfg
- type TokenProvider
- type User
- type UserCreds
- type UserExtractorFn
- type UserGetter
- type UserGetterProvider
- type UserGetterProxy
- type UserGetterProxyOption
- type WrongHMAC
Examples ¶
Constants ¶
const ( AuthzHeaderKey = "Authorization" TsHeaderKey = "X-Date" SaltHeaderKey = "X-Data-Salt" )
Our constant header names
Variables ¶
This section is empty.
Functions ¶
func AddUserToken ¶
AddUserToken adds the given token as a bearer token to the request.
func AddUserTokenToClientRequest ¶
func AddUserTokenToClientRequest(rq runtime.ClientRequest, token string)
AddUserTokenToClientRequest to support openapi
func CreateToken ¶ added in v0.5.0
CreateToken creates a jwt token with the given claims
func CreateTokenAndKeys ¶ added in v0.5.0
func CreateTokenAndKeys(cfg *TokenCfg) (token string, pubKey jose.JSONWebKey, privKey jose.JSONWebKey, err error)
CreateTokenAndKeys creates a keyset and token
func CreateWebkeyPair ¶ added in v0.5.0
func CreateWebkeyPair(alg jose.SignatureAlgorithm, use string, keylenBits int) (jose.JSONWebKey, jose.JSONWebKey, error)
CreateWebkeyPair creates a JSONWebKey-Pair. alg is one of jose signature-algorithm constants, e.g. jose.RS256. use is "sig" for signature or "enc" for encryption, see https://tools.ietf.org/html/rfc7517#page-6 Arbitrary keylenBits are not supported for Elliptic Curve Algs, here the Bits must match the Algorithms.
func ExtractBearer ¶ added in v0.5.0
ExtractBearer extracts the Bearer Token from the request header
func GenerateSigningKey ¶ added in v0.5.0
func GenerateSigningKey(alg jose.SignatureAlgorithm, bits int) (crypto.PublicKey, crypto.PrivateKey, error)
GenerateSigningKey generates a keypair for corresponding SignatureAlgorithm.
func GenerateTokenAndKeyServer ¶ added in v0.5.0
func GenerateTokenAndKeyServer(tc *TokenCfg, tokenProvider TokenProvider, opts ...KeyServerOption) (srv *httptest.Server, token string, err error)
GenerateTokenAndKeyServer starts keyserver, patches tokenCfg (issuer), generates token. This method is intended for test purposes, where you need a server that provides '.well-known/openid-configuration' and '/keys' endpoints.
func MustCreateTokenAndKeys ¶ added in v0.5.0
func MustCreateTokenAndKeys(cfg *TokenCfg) (token string, pubKey jose.JSONWebKey, privKey jose.JSONWebKey)
MustCreateTokenAndKeys creates a keyset and token, panics on error
func MustMakeSigner ¶ added in v0.5.0
func MustMakeSigner(alg jose.SignatureAlgorithm, k any) jose.Signer
MustMakeSigner creates a Signer and panics if an error occurs
func ParseTokenClaimsUnvalidated ¶ added in v0.5.0
ParseTokenClaimsUnvalidated returns the UNVALIDATED claims from the bearer token in the authentication header.
Types ¶
type Annotations ¶ added in v0.5.0
type Claims ¶
type Claims struct { jwt.RegisteredClaims Audience any `json:"aud,omitempty"` Groups []string `json:"groups"` EMail string `json:"email"` Name string `json:"name"` FederatedClaims map[string]string `json:"federated_claims"` // added for parsing of "new" style tokens Roles []string `json:"roles"` }
Claims we overwrite the Audience because in the current version of the jwt library this is not an array.
type Dex ¶
type Dex struct {
// contains filtered or unexported fields
}
A Dex ...
type GenericOIDC ¶ added in v0.5.0
type GenericOIDC struct {
// contains filtered or unexported fields
}
GenericOIDC is Token Validator and UserGetter for Tokens issued by generic OIDC-Providers.
func NewGenericOIDC ¶ added in v0.5.0
func NewGenericOIDC(ic *IssuerConfig, opts ...GenericOIDCOption) (*GenericOIDC, error)
NewGenericOIDC creates a new GenericOIDC.
type GenericOIDCCfg ¶ added in v0.5.0
type GenericOIDCCfg struct { SupportedSigningAlgs []string Timeout time.Duration UserExtractorFn GenericUserExtractorFn }
GenericOIDCCfg properties that can be modified by Options
type GenericOIDCClaims ¶ added in v0.5.0
type GenericOIDCClaims struct { jwt.Claims Name string `json:"name"` PreferredUsername string `json:"preferred_username"` EMail string `json:"email"` Roles []string `json:"roles"` }
GenericOIDCClaims https://openid.net/specs/openid-connect-core-1_0.html Audience(s) that this ID Token is intended for. It MUST contain the OAuth 2.0 client_id of the Relying Party as an audience value. It MAY also contain identifiers for other audiences. In the general case, the aud value is an array of case sensitive strings. In the common special case when there is one audience, the aud value MAY be a single case sensitive string.
func (*GenericOIDCClaims) Username ¶ added in v0.5.3
func (g *GenericOIDCClaims) Username() string
type GenericOIDCOption ¶ added in v0.5.0
type GenericOIDCOption func(oidc *GenericOIDCCfg)
GenericOIDCOption provides means to configure GenericOIDC
func AllowedSignAlgs ¶ added in v0.5.0
func AllowedSignAlgs(algs []string) GenericOIDCOption
AllowedSignAlgs configures the allowed SigningAlgorithms, e.g. RS256, RS512,...
func GenericUserExtractor ¶ added in v0.5.0
func GenericUserExtractor(fn GenericUserExtractorFn) GenericOIDCOption
GenericUserExtractor configures the GenericUserExtractorFn to extract the User from a token
func Timeout ¶ added in v0.5.0
func Timeout(timeout time.Duration) GenericOIDCOption
type GenericUserExtractorFn ¶ added in v0.5.0
type GenericUserExtractorFn func(ic *IssuerConfig, claims *GenericOIDCClaims) (*User, error)
GenericUserExtractorFn extracts the User and Claims
type HMACAuth ¶
type HMACAuth struct { Lifetime time.Duration Type string AuthUser User // contains filtered or unexported fields }
A HMACAuth is an authenticator which uses a hmac calculation.
Example ¶
u := User{Name: "Bicycle Repair Man"} // Use the authtype 'mytype' and the shared key (1,2,3) // we also connect a user and set a lifetime hm := NewHMACAuth( "mytype", []byte{1, 2, 3}, WithUser(u), WithLifetime(10*time.Second)) fmt.Println(hm.AuthUser.Name) fmt.Println(hm.Lifetime) fmt.Println(hm.Type) // the key is not accessible fmt.Println(hm.key)
Output: Bicycle Repair Man 10s mytype [1 2 3]
func NewHMACAuth ¶
func NewHMACAuth(authtype string, key []byte, opts ...HMACAuthOption) HMACAuth
NewHMACAuth returns a new HMACAuth initialized with the given key. A service implementation and a client must share the same key and authtype. The authtype will be transported as a scheme in the "Authentication" header. The key has to be private and will never be transmitted over the wire.
func (*HMACAuth) AddAuth ¶
AddAuth adds the needed headers to the given request so the given values in the vals-array are correctly signed. This function can be used by a client to enhance the request before submitting it.
func (*HMACAuth) AddAuthToClientRequest ¶
func (hma *HMACAuth) AddAuthToClientRequest(rq runtime.ClientRequest, t time.Time)
AddAuthToClientRequest to support openapi too
func (*HMACAuth) AuthHeaders ¶
AuthHeaders creates the necessary headers
func (*HMACAuth) User ¶
User calculates the hmac from header values. The input-values for the calculation are: Date-Header, Request-Method, Request-Content. If the result does not match the HMAC in the header, this function returns an error. Otherwise it returns the user which is connected to this hmac-auth.
Example ¶
u := User{Name: "Bicycle Repair Man"} // Use the authtype 'mytype' and the shared key (1,2,3) // we also set the lifetime to zero so the test will work here // never do this in production. hm := NewHMACAuth( "mytype", []byte{1, 2, 3}, WithUser(u), WithLifetime(0)) mybody := []byte{4, 5, 6} rq := httptest.NewRequest(http.MethodGet, "/myurl", bytes.NewReader(mybody)) t := time.Date(2019, time.January, 16, 14, 44, 45, 123, time.UTC) // now add a HMCA with the given date and the body {4,5,6} hm.AddAuth(rq, t, mybody) usr, _ := hm.User(rq) fmt.Println(usr.Name)
Output: Bicycle Repair Man
func (*HMACAuth) UserFromRequestData ¶
func (hma *HMACAuth) UserFromRequestData(requestData RequestData) (*User, error)
UserFromRequestData calculates the hmac from header values. The input-values for the calculation are: Date-Header, Request-Method, Request-Content. If the result does not match the HMAC in the header, this function returns an error. Otherwise it returns the user which is connected to this hmac-auth.
type HMACAuthOption ¶
type HMACAuthOption func(*HMACAuth)
HMACAuthOption is a option type for HMACAuth
func WithLifetime ¶
func WithLifetime(max time.Duration) HMACAuthOption
WithLifetime sets the lifetime which is connected to this HMAC auth. If the lifetime is zero, there will be no datetime checking. Do not do this in productive code (only useful in tests).
Example ¶
hm := NewHMACAuth("mytype", []byte{1, 2, 3}, WithLifetime(10*time.Second)) fmt.Println(hm.Lifetime)
Output: 10s
func WithUser ¶
func WithUser(u User) HMACAuthOption
WithUser sets the user which is connected to this HMAC auth.
Example ¶
u := User{Name: "Bicycle Repair Man"} hm := NewHMACAuth("mytype", []byte{1, 2, 3}, WithUser(u)) fmt.Println(hm.AuthUser.Name)
Output: Bicycle Repair Man
type IssuerConfig ¶ added in v0.5.0
type IssuerConfig struct { Annotations Annotations Tenant string Issuer string ClientID string }
func (*IssuerConfig) String ¶ added in v0.5.0
func (i *IssuerConfig) String() string
type IssuerListProvider ¶ added in v0.5.0
type IssuerListProvider func() ([]*IssuerConfig, error)
IssuerListProvider returns the list of allowed IssuerConfigs
type IssuerNotFound ¶ added in v0.5.0
type IssuerNotFound struct{}
func NewIssuerNotFound ¶ added in v0.5.0
func NewIssuerNotFound() IssuerNotFound
func (IssuerNotFound) Error ¶ added in v0.5.0
func (i IssuerNotFound) Error() string
type KeyServerConfig ¶ added in v0.5.0
type KeyServerConfig struct {
// contains filtered or unexported fields
}
type KeyServerOption ¶ added in v0.5.0
type KeyServerOption func(cfg *KeyServerConfig)
func KeyResponseTimeDelay ¶ added in v0.5.0
func KeyResponseTimeDelay(delay time.Duration) KeyServerOption
type MultiIssuerCache ¶ added in v0.5.0
type MultiIssuerCache struct {
// contains filtered or unexported fields
}
MultiIssuerCache provides a UserGetter that is backed by multiple IssuerConfigs that are cached for a configurable duration.
func NewMultiIssuerCache ¶ added in v0.5.0
func NewMultiIssuerCache(log *slog.Logger, ilp IssuerListProvider, ugp UserGetterProvider, opts ...MultiIssuerUserGetterOption) (*MultiIssuerCache, error)
NewMultiIssuerCache creates a new MultiIssuerCache with given options if log is nil, slog is instantiated
type MultiIssuerUserGetterOption ¶ added in v0.5.0
type MultiIssuerUserGetterOption func(mic *MultiIssuerCache) *MultiIssuerCache
Option
func IssuerReloadInterval ¶ added in v0.5.0
func IssuerReloadInterval(duration time.Duration) MultiIssuerUserGetterOption
IssuerReloadInterval lets the client set the issuer cache duration
func IssuerRetryInterval ¶ added in v0.8.2
func IssuerRetryInterval(duration time.Duration) MultiIssuerUserGetterOption
IssuerRetryInterval lets the client set the issuer cache retry sleep period
type Option ¶
Option configures Dex
func AlgorithmsWhitelist ¶ added in v0.4.0
AlgorithmsWhitelist adds given algorithms as allowed
func JWTParserOptions ¶ added in v0.9.0
func JWTParserOptions(opt jwt.ParserOption) Option
func UserExtractor ¶
func UserExtractor(fn UserExtractorFn) Option
UserExtractor extracts the user with the given extractorfunc
type RequestData ¶
type RequestData struct { Method string AuthzHeader string TimestampHeader string SaltHeader string }
RequestData wraps the http request data
type RequestDataGetter ¶
type RequestDataGetter func() RequestData
RequestDataGetter is a supplied func which returns the RequestData
type TokenCfg ¶ added in v0.5.0
type TokenCfg struct { Alg jose.SignatureAlgorithm KeyBitlength int IssuerUrl string Audience []string ExpiresAt time.Time IssuedAt time.Time Id string Subject string Name string PreferredName string Email string Roles []string }
TokenCfg contains the data for filling the token
func DefaultTokenCfg ¶ added in v0.5.0
func DefaultTokenCfg() *TokenCfg
DefaultTokenCfg creates a TokenCfg filled with default values
type TokenProvider ¶ added in v0.5.0
TokenProvider creates the token with the given TokenCfg
type User ¶
type User struct { EMail string Name string Groups []ResourceAccess Tenant string Issuer string Subject string }
A User is the current user who is executing a rest function.
func DefaultGenericUserExtractor ¶ added in v0.5.0
func DefaultGenericUserExtractor(ic *IssuerConfig, claims *GenericOIDCClaims) (*User, error)
DefaultGenericUserExtractor is the default implementation of how to extract the User from the token.
func GetUserFromContext ¶
GetUserFromContext returns the current user from the context. If no user is set it returns a guest with no rights.
func (*User) HasGroup ¶
func (u *User) HasGroup(grps ...ResourceAccess) bool
HasGroup returns true if the user has at least one of the given groups.
type UserCreds ¶
type UserCreds struct {
// contains filtered or unexported fields
}
UserCreds stores different methods for user extraction from a request.
func NewCreds ¶
NewCreds returns a credential checker which tries to pull out the current user of a request. You can set many different HMAC auth'ers but only one for bearer tokens.
type UserExtractorFn ¶
UserExtractorFn extracts the User and Claims
type UserGetter ¶
A UserGetter returns the authenticated user from the request.
type UserGetterProvider ¶ added in v0.5.0
type UserGetterProvider func(ic *IssuerConfig) (UserGetter, error)
UserGetterProvider creates UserGetter for the given IssuerConfig
type UserGetterProxy ¶ added in v0.5.0
type UserGetterProxy struct {
// contains filtered or unexported fields
}
UserGetterProxy switches between UserGetters depending on issuer/clientid of the token in the request.
func NewUserGetterProxy ¶ added in v0.5.0
func NewUserGetterProxy(defaultUG UserGetter, opts ...UserGetterProxyOption) *UserGetterProxy
NewUserGetterProxy creates a new UserGetterProxy with the given default UserGetter which is used if no other match is found.
type UserGetterProxyOption ¶ added in v0.5.0
type UserGetterProxyOption func(ug *UserGetterProxy)
UserGetterProxyOption defines the signature of init option-parameter
func UserGetterProxyMapping ¶ added in v0.5.0
func UserGetterProxyMapping(issuer, clientid string, userGetter UserGetter) UserGetterProxyOption
UserGetterProxyMapping adds the given UserGetter for the specified issuer/clientid combination that takes precedence over the default UserGetter if matched.