security

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2020 License: MIT Imports: 15 Imported by: 10

README

security

Build Status GoDoc Go Report Card codecov License

JWT and HMAC based security primitives for authentication of services and users.

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

Examples

Constants

View Source
const (
	AuthzHeaderKey = "Authorization"
	TsHeaderKey    = "X-Date"
	SaltHeaderKey  = "X-Data-Salt"
)

Our constant header names

Variables

This section is empty.

Functions

func AddUserToken

func AddUserToken(rq *http.Request, token string)

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 PutUserInContext

func PutUserInContext(ctx context.Context, u *User) context.Context

PutUserInContext puts the given user as a value in the context.

Types

type Claims

type Claims struct {
	jwt.StandardClaims
	Audience        interface{}       `json:"aud,omitempty"`
	Groups          []string          `json:"groups"`
	EMail           string            `json:"email"`
	Name            string            `json:"name"`
	FederatedClaims map[string]string `json:"federated_claims"`
}

Claims we overwrite the Audience because in the current version of the jwt library this is not an array.

type CredsOpt

type CredsOpt func(*UserCreds)

CredsOpt is a option setter for UserCreds

func WithDex

func WithDex(d *Dex) CredsOpt

WithDex sets the dex auther.

func WithHMAC

func WithHMAC(hma HMACAuth) CredsOpt

WithHMAC appends the given HMACAuth to the list of allowed authers.

type Dex

type Dex struct {
	// contains filtered or unexported fields
}

A Dex ...

func NewDex

func NewDex(baseurl string) (*Dex, error)

NewDex returns a new Dex.

func (*Dex) User

func (dx *Dex) User(rq *http.Request) (*User, error)

User implements the UserGetter to get a user from the request.

func (*Dex) With

func (dx *Dex) With(opts ...Option) *Dex

With sets available Options

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

func (hma *HMACAuth) AddAuth(rq *http.Request, t time.Time, body []byte)

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

func (hma *HMACAuth) AuthHeaders(method string, t time.Time) map[string]string

AuthHeaders creates the necessary headers

func (*HMACAuth) User

func (hma *HMACAuth) User(rq *http.Request) (*User, error)

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 Option

type Option func(dex *Dex) *Dex

Option configures Dex

func AlgorithmsWhitelist added in v0.4.0

func AlgorithmsWhitelist(algNames []string) Option

AlgorithmsWhitelist adds given algorithms as allowed

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 ResourceAccess

type ResourceAccess string

ResourceAccess is the type for our groups

type User

type User struct {
	EMail  string
	Name   string
	Groups []ResourceAccess
	Tenant string
}

A User is the current user who is executing a rest function.

func GetUser

func GetUser(rq *http.Request) *User

GetUser reads the current user from the request.

func GetUserFromContext

func GetUserFromContext(ctx context.Context) *User

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

func NewCreds(opts ...CredsOpt) *UserCreds

NewCreds returns a credention 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.

func (*UserCreds) User

func (uc *UserCreds) User(rq *http.Request) (*User, error)

User pulls out a user from the request. It uses all authers which where specified when creating this usercred. the first auther which returns a user wins. if no auther returns a user, a guest with no rights will be returned.

type UserExtractorFn

type UserExtractorFn func(claims *Claims) (*User, error)

UserExtractorFn extracts the User and Claims

type UserGetter

type UserGetter interface {
	User(rq *http.Request) (*User, error)
}

A UserGetter returns the authenticated user from the request.

type WrongHMAC

type WrongHMAC struct {
	Got  string
	Want string
}

WrongHMAC is an error which contains the two hmacs which differ. A caller can use this values to log the computed value.

func (*WrongHMAC) Error

func (w *WrongHMAC) Error() string

Jump to

Keyboard shortcuts

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