Documentation ¶
Index ¶
- Constants
- Variables
- func BearerFromContext(ctx context.Context) (result string, err error)
- func ContextWithToken(parent context.Context, token *jwt.Token) context.Context
- func InitiateAuthCode(clientID string) (string, error)
- func TokenFromContext(ctx context.Context) (result *jwt.Token, err error)
- type DeviceAuthConfig
- type Handler
- type HandlerBuilder
- func (b *HandlerBuilder) ACLFile(value string) *HandlerBuilder
- func (b *HandlerBuilder) Build() (handler *Handler, err error)
- func (b *HandlerBuilder) Cookie(value string) *HandlerBuilder
- func (b *HandlerBuilder) Error(value string) *HandlerBuilder
- func (b *HandlerBuilder) KeysCAs(value *x509.CertPool) *HandlerBuilder
- func (b *HandlerBuilder) KeysFile(value string) *HandlerBuilder
- func (b *HandlerBuilder) KeysInsecure(value bool) *HandlerBuilder
- func (b *HandlerBuilder) KeysURL(value string) *HandlerBuilder
- func (b *HandlerBuilder) Logger(value logging.Logger) *HandlerBuilder
- func (b *HandlerBuilder) Next(value http.Handler) *HandlerBuilder
- func (b *HandlerBuilder) OperationID(value func(r *http.Request) string) *HandlerBuilder
- func (b *HandlerBuilder) Public(value string) *HandlerBuilder
- func (b *HandlerBuilder) Service(value string) *HandlerBuilder
- func (b *HandlerBuilder) Tolerance(value time.Duration) *HandlerBuilder
- type TransportWrapper
- func (w *TransportWrapper) Client() (id, secret string)
- func (w *TransportWrapper) Close() error
- func (w *TransportWrapper) Logger() logging.Logger
- func (w *TransportWrapper) Scopes() []string
- func (w *TransportWrapper) TokenURL() string
- func (w *TransportWrapper) Tokens(ctx context.Context, expiresIn ...time.Duration) (access, refresh string, err error)
- func (w *TransportWrapper) User() (user, password string)
- func (w *TransportWrapper) Wrap(transport http.RoundTripper) http.RoundTripper
- type TransportWrapperBuilder
- func (b *TransportWrapperBuilder) Agent(agent string) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) Build(ctx context.Context) (result *TransportWrapper, err error)
- func (b *TransportWrapperBuilder) Client(id string, secret string) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) Insecure(flag bool) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) Logger(value logging.Logger) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) MetricsRegisterer(value prometheus.Registerer) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) MetricsSubsystem(value string) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) Scopes(values ...string) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) TokenURL(url string) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) Tokens(tokens ...string) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) TransportWrapper(value func(http.RoundTripper) http.RoundTripper) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) TransportWrappers(values ...func(http.RoundTripper) http.RoundTripper) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) TrustedCA(value interface{}) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) TrustedCAs(values ...interface{}) *TransportWrapperBuilder
- func (b *TransportWrapperBuilder) User(name string, password string) *TransportWrapperBuilder
Constants ¶
const ( RedirectURL = "http://127.0.0.1" RedirectPort = "9998" DefaultAuthURL = "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/auth" CallbackHandler = "/oauth/callback" )
const ( // #nosec G101 DefaultTokenURL = "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token" DefaultClientID = "cloud-services" DefaultClientSecret = "" )
Default values:
const (
DeviceAuthURL = "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/auth/device"
)
Variables ¶
var DefaultScopes = []string{
"openid",
}
DefaultScopes is the ser of scopes used by default:
Functions ¶
func BearerFromContext ¶
BearerFromContext extracts the bearer token of the user from the context. If no user is found in the context then the result will be the empty string.
func ContextWithToken ¶
ContextWithToken creates a new context containing the given token.
func InitiateAuthCode ¶ added in v0.1.394
func TokenFromContext ¶
TokenFromContext extracts the JSON web token of the user from the context. If no token is found in the context then the result will be nil.
Types ¶
type DeviceAuthConfig ¶ added in v0.1.394
type DeviceAuthConfig struct { DeviceAuthResponse *oauth2.DeviceAuthResponse ClientID string // contains filtered or unexported fields }
func (*DeviceAuthConfig) InitiateDeviceAuth ¶ added in v0.1.394
func (d *DeviceAuthConfig) InitiateDeviceAuth(ctx context.Context) (*DeviceAuthConfig, error)
Step 1: Initiates device code flow and returns the device auth config. After running, use your DeviceAuthConfig to display the user code and verification URI
fmt.Printf("To continue login, navigate to %v and enter code %v\n", deviceAuthResp.VerificationURI, deviceAuthResp.UserCode) fmt.Printf("Checking status every %v seconds...\n", deviceAuthResp.Interval)
func (*DeviceAuthConfig) PollForTokenExchange ¶ added in v0.1.394
func (d *DeviceAuthConfig) PollForTokenExchange(ctx context.Context) (string, error)
Step 2: Initiates polling for token exchange and returns a refresh token
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler is an HTTP handler that checks authentication using the JWT tokens from the authorization header.
type HandlerBuilder ¶
type HandlerBuilder struct {
// contains filtered or unexported fields
}
HandlerBuilder contains the data and logic needed to create a new authentication handler. Don't create objects of this type directly, use the NewHandler function instead.
func NewHandler ¶
func NewHandler() *HandlerBuilder
NewHandler creates a builder that can then be configured and used to create authentication handlers.
func (*HandlerBuilder) ACLFile ¶
func (b *HandlerBuilder) ACLFile(value string) *HandlerBuilder
ACLFile sets a file that contains items of the access control list. This should be a YAML file with the following format:
claim: email pattern: ^.*@redhat\.com$
claim: sub pattern: ^f:b3f7b485-7184-43c8-8169-37bd6d1fe4aa:myuser$
The claim field is the name of the claim of the JWT token that will be checked. The pattern field is a regular expression. If the claim matches the regular expression then access will be allowed.
If the ACL is empty then access will be allowed to all JWT tokens.
If the ACL has at least one item then access will be allowed only to tokens that match at least one of the items.
func (*HandlerBuilder) Build ¶
func (b *HandlerBuilder) Build() (handler *Handler, err error)
Build uses the data stored in the builder to create a new authentication handler.
func (*HandlerBuilder) Cookie ¶ added in v0.0.329
func (b *HandlerBuilder) Cookie(value string) *HandlerBuilder
Cookie sets the name of the cookie where the bearer token will be extracted from when the `Authorization` header isn't present. The default is `cs_jwt`.
func (*HandlerBuilder) Error ¶ added in v0.0.329
func (b *HandlerBuilder) Error(value string) *HandlerBuilder
Error sets the error identifier that will be used to generate JSON error responses. For example, if the value is `123` then the JSON for error responses will be like this:
{ "kind": "Error", "id": "11", "href": "/api/clusters_mgmt/v1/errors/11", "code": "CLUSTERS-MGMT-11", "reason": "Bearer token is expired" }
When this isn't explicitly provided the value will be `401`. Note that changing this doesn't change the HTTP response status, that will always be 401.
func (*HandlerBuilder) KeysCAs ¶
func (b *HandlerBuilder) KeysCAs(value *x509.CertPool) *HandlerBuilder
KeysCAs sets the certificate authorities that will be trusted when verifying the certificate of the web server where keys are loaded from.
func (*HandlerBuilder) KeysFile ¶
func (b *HandlerBuilder) KeysFile(value string) *HandlerBuilder
KeysFile sets the location of a file containing a JSON web key set that will be used to verify the signatures of the tokens. The keys from this file will be loaded when a token is received containing an unknown key identifier.
At least one keys file or one keys URL is mandatory.
func (*HandlerBuilder) KeysInsecure ¶
func (b *HandlerBuilder) KeysInsecure(value bool) *HandlerBuilder
KeysInsecure sets the flag that indicates that the certificate of the web server where the keys are loaded from should not be checked. The default is false and changing it to true makes the token verification insecure, so refrain from doing that in security sensitive environments.
func (*HandlerBuilder) KeysURL ¶
func (b *HandlerBuilder) KeysURL(value string) *HandlerBuilder
KeysURL sets the URL containing a JSON web key set that will be used to verify the signatures of the tokens. The keys from these URLs will be loaded when a token is received containing an unknown key identifier.
At least one keys file or one keys URL is mandatory.
func (*HandlerBuilder) Logger ¶
func (b *HandlerBuilder) Logger(value logging.Logger) *HandlerBuilder
Logger sets the logger that the middleware will use to send messages to the log. This is mandatory.
func (*HandlerBuilder) Next ¶
func (b *HandlerBuilder) Next(value http.Handler) *HandlerBuilder
Next sets the HTTP handler that will be called when the authentication handler has authenticated correctly the request. This is mandatory.
func (*HandlerBuilder) OperationID ¶ added in v0.0.329
func (b *HandlerBuilder) OperationID(value func(r *http.Request) string) *HandlerBuilder
OperationID sets a function that will be called each time an error is detected, passing the details of the request that caused the error. The value returned by the function will be included in the `operation_id` field of the JSON error response. For example, if the function returns `123` the generated JSON error response will be like this:
{ "kind": "Error", "id": "401", "href": "/api/clusters_mgmt/v1/errors/401", "code": "CLUSTERS-MGMT-401", "reason": "Bearer token is expired". "operation_id": "123" }
For example, if the operation identifier is available in an HTTP header named `X-Operation-ID` then the handler can be configured like this to use it:
handler, err := authentication.NewHandler(). Logger(logger). KeysURL("https://..."). OperationID(func(r *http.Request) string { return r.Header.Get("X-Operation-ID") }). Next(next). Build() if err != nil { ... }
If the function returns an empty string then the `operation_id` field will not be added.
By default there is no function configured for this, so no `operation_id` field will be added.
func (*HandlerBuilder) Public ¶
func (b *HandlerBuilder) Public(value string) *HandlerBuilder
Public sets a regular expression that defines the parts of the URL space that considered public, and therefore require no authentication. This method may be called multiple times and then all the given regular expressions will be used to check what parts of the URL space are public.
func (*HandlerBuilder) Service ¶ added in v0.0.329
func (b *HandlerBuilder) Service(value string) *HandlerBuilder
Service sets the identifier of the service that will be used to generate error codes. For example, if the value is `my_service` then the JSON for error responses will be like this:
{ "kind": "Error", "id": "401", "href": "/api/clusters_mgmt/v1/errors/401", "code": "MY-SERVICE-401", "reason": "Bearer token is expired" }
When this isn't explicitly provided the value will be extracted from the second segment of the request path. For example, if the request URL is `/api/clusters_mgmt/v1/cluster` the value will be `clusters_mgmt`.
func (*HandlerBuilder) Tolerance ¶ added in v0.0.329
func (b *HandlerBuilder) Tolerance(value time.Duration) *HandlerBuilder
Tolerance sets the maximum time that a token will be considered valid after it has expired. For example, to accept requests with tokens that have expired up to five minutes ago:
handler, err := authentication.NewHandler(). Logger(logger). KeysURL("https://..."). Tolerance(5 * time.Minute). Next(next). Build() if err != nil { ... }
The default value is zero tolerance.
type TransportWrapper ¶ added in v0.0.329
type TransportWrapper struct {
// contains filtered or unexported fields
}
TransportWrapper contains the data and logic needed to wrap an HTTP round tripper with another one that adds authorization tokens to requests.
func (*TransportWrapper) Client ¶ added in v0.0.329
func (w *TransportWrapper) Client() (id, secret string)
Client returns OpenID client identifier and secret that the wrapper is using to request OpenID access tokens.
func (*TransportWrapper) Close ¶ added in v0.0.329
func (w *TransportWrapper) Close() error
Close releases all the resources used by the wrapper.
func (*TransportWrapper) Logger ¶ added in v0.0.329
func (w *TransportWrapper) Logger() logging.Logger
Logger returns the logger that is used by the wrapper.
func (*TransportWrapper) Scopes ¶ added in v0.0.329
func (w *TransportWrapper) Scopes() []string
Scopes returns the OpenID scopes that the wrapper is using to request OpenID access tokens.
func (*TransportWrapper) TokenURL ¶ added in v0.0.329
func (w *TransportWrapper) TokenURL() string
TokenURL returns the URL that the connection is using request OpenID access tokens.
func (*TransportWrapper) Tokens ¶ added in v0.0.329
func (w *TransportWrapper) Tokens(ctx context.Context, expiresIn ...time.Duration) (access, refresh string, err error)
Tokens returns the access and refresh tokens that are currently in use by the wrapper. If it is necessary to request new tokens because they weren't requested yet, or because they are expired, this method will do it and will return an error if it fails.
If new tokens are needed the request will be retried with an exponential backoff.
func (*TransportWrapper) User ¶ added in v0.0.329
func (w *TransportWrapper) User() (user, password string)
User returns the user name and password that the wrapper is using to request OpenID access tokens.
func (*TransportWrapper) Wrap ¶ added in v0.0.329
func (w *TransportWrapper) Wrap(transport http.RoundTripper) http.RoundTripper
Wrap creates a new round tripper that wraps the given one and populates the authorization header.
type TransportWrapperBuilder ¶ added in v0.0.329
type TransportWrapperBuilder struct {
// contains filtered or unexported fields
}
TransportWrapperBuilder contains the data and logic needed to add to requests the authorization token. Don't create objects of this type directly; use the NewTransportWrapper function instead.
func NewTransportWrapper ¶ added in v0.0.329
func NewTransportWrapper() *TransportWrapperBuilder
NewTransportWrapper creates a new builder that can then be used to configure and create a new authentication round tripper.
func (*TransportWrapperBuilder) Agent ¶ added in v0.0.329
func (b *TransportWrapperBuilder) Agent(agent string) *TransportWrapperBuilder
Agent sets the `User-Agent` header that the round trippers will use in all the HTTP requests. The default is `OCM-SDK` followed by an slash and the version of the SDK, for example `OCM/0.0.0`.
func (*TransportWrapperBuilder) Build ¶ added in v0.0.329
func (b *TransportWrapperBuilder) Build(ctx context.Context) (result *TransportWrapper, err error)
Build uses the information stored in the builder to create a new transport wrapper.
func (*TransportWrapperBuilder) Client ¶ added in v0.0.329
func (b *TransportWrapperBuilder) Client(id string, secret string) *TransportWrapperBuilder
Client sets OpenID client identifier and secret that will be used to request OpenID tokens. The default identifier is `cloud-services`. The default secret is the empty string. When these two values are provided and no user name and password is provided, the round trippers will use the client credentials grant to obtain the token. For example, to create a connection using the client credentials grant do the following:
// Use the client credentials grant: wrapper, err := authentication.NewTransportWrapper(). Client("myclientid", "myclientsecret"). Build()
Note that some OpenID providers (Keycloak, for example) require the client identifier also for the resource owner password grant. In that case use the set only the identifier, and let the secret blank. For example:
// Use the resource owner password grant: wrapper, err := authentication.NewTransportWrapper(). User("myuser", "mypassword"). Client("myclientid", ""). Build()
Note the empty client secret.
func (*TransportWrapperBuilder) Insecure ¶ added in v0.0.329
func (b *TransportWrapperBuilder) Insecure(flag bool) *TransportWrapperBuilder
Insecure enables insecure communication with the OpenID server. This disables verification of TLS certificates and host names and it isn't recommended for a production environment.
func (*TransportWrapperBuilder) Logger ¶ added in v0.0.329
func (b *TransportWrapperBuilder) Logger(value logging.Logger) *TransportWrapperBuilder
Logger sets the logger that will be used by the wrapper and by the transports that it creates.
func (*TransportWrapperBuilder) MetricsRegisterer ¶ added in v0.0.329
func (b *TransportWrapperBuilder) MetricsRegisterer( value prometheus.Registerer) *TransportWrapperBuilder
MetricsRegisterer sets the Prometheus registerer that will be used to register the metrics. The default is to use the default Prometheus registerer and there is usually no need to change that. This is intended for unit tests, where it is convenient to have a registerer that doesn't interfere with the rest of the system.
func (*TransportWrapperBuilder) MetricsSubsystem ¶ added in v0.0.329
func (b *TransportWrapperBuilder) MetricsSubsystem(value string) *TransportWrapperBuilder
MetricsSubsystem sets the name of the subsystem that will be used by the wrapper to register metrics with Prometheus. If this isn't explicitly specified, or if it is an empty string, then no metrics will be registered. For example, if the value is `api_outbound` then the following metrics will be registered:
api_outbound_token_request_count - Number of token requests sent. api_outbound_token_request_duration_sum - Total time to send token requests, in seconds. api_outbound_token_request_duration_count - Total number of token requests measured. api_outbound_token_request_duration_bucket - Number of token requests organized in buckets.
The duration buckets metrics contain an `le` label that indicates the upper bound. For example if the `le` label is `1` then the value will be the number of requests that were processed in less than one second.
code - HTTP response code, for example 200 or 500.
The value of the `code` label will be zero when sending the request failed without a response code, for example if it wasn't possible to open the connection, or if there was a timeout waiting for the response.
Note that setting this attribute is not enough to have metrics published, you also need to create and start a metrics server, as described in the documentation of the Prometheus library.
func (*TransportWrapperBuilder) Scopes ¶ added in v0.0.329
func (b *TransportWrapperBuilder) Scopes(values ...string) *TransportWrapperBuilder
Scopes sets the OpenID scopes that will be included in the token request. The default is to use the `openid` scope. If this method is used then that default will be completely replaced, so you will need to specify it explicitly if you want to use it. For example, if you want to add the scope 'myscope' without loosing the default you will have to do something like this:
// Create a wrapper with the default 'openid' scope and some additional scopes: wrapper, err := authentication.NewTransportWrapper(). User("myuser", "mypassword"). Scopes("openid", "myscope", "yourscope"). Build()
If you just want to use the default 'openid' then there is no need to use this method.
func (*TransportWrapperBuilder) TokenURL ¶ added in v0.0.329
func (b *TransportWrapperBuilder) TokenURL(url string) *TransportWrapperBuilder
TokenURL sets the URL that will be used to request OpenID access tokens. The default is `https://sso.redhat.com/auth/realms/cloud-services/protocol/openid-connect/token`.
func (*TransportWrapperBuilder) Tokens ¶ added in v0.0.329
func (b *TransportWrapperBuilder) Tokens(tokens ...string) *TransportWrapperBuilder
Tokens sets the OpenID tokens that will be used to authenticate. Multiple types of tokens are accepted, and used according to their type. For example, you can pass a single access token, or an access token and a refresh token, or just a refresh token. If no token is provided then the round trippers will the user name and password or the client identifier and client secret (see the User and Client methods) to request new ones.
If the wrapper is created with these tokens and no user or client credentials, it will stop working when both tokens expire. That can happen, for example, if the connection isn't used for a period of time longer than the life of the refresh token.
func (*TransportWrapperBuilder) TransportWrapper ¶ added in v0.0.329
func (b *TransportWrapperBuilder) TransportWrapper( value func(http.RoundTripper) http.RoundTripper) *TransportWrapperBuilder
TransportWrapper adds a function that will be used to wrap the transports of the HTTP client used to request tokens. If used multiple times the transport wrappers will be called in the same order that they are added.
func (*TransportWrapperBuilder) TransportWrappers ¶ added in v0.0.329
func (b *TransportWrapperBuilder) TransportWrappers( values ...func(http.RoundTripper) http.RoundTripper) *TransportWrapperBuilder
TransportWrappers adds a list of functions that will be used to wrap the transports of the HTTP client used to request tokens
func (*TransportWrapperBuilder) TrustedCA ¶ added in v0.0.329
func (b *TransportWrapperBuilder) TrustedCA(value interface{}) *TransportWrapperBuilder
TrustedCA sets a source that contains he certificate authorities that will be trusted by the HTTP client used to request tokens. If this isn't explicitly specified then the clients will trust the certificate authorities trusted by default by the system. The value can be a *x509.CertPool or a string, anything else will cause an error when Build method is called. If it is a *x509.CertPool then the value will replace any other source given before. If it is a string then it should be the name of a PEM file. The contents of that file will be added to the previously given sources.
func (*TransportWrapperBuilder) TrustedCAs ¶ added in v0.0.329
func (b *TransportWrapperBuilder) TrustedCAs(values ...interface{}) *TransportWrapperBuilder
TrustedCAs sets a list of sources that contains he certificate authorities that will be trusted by the HTTP client used to request tokens. See the documentation of the TrustedCA method for more information about the accepted values.
func (*TransportWrapperBuilder) User ¶ added in v0.0.329
func (b *TransportWrapperBuilder) User(name string, password string) *TransportWrapperBuilder
User sets the user name and password that will be used to request OpenID access tokens. When these two values are provided the round trippers will use the resource owner password grant type to obtain the token. For example:
// Use the resource owner password grant: wrapper, err := authentication.NewTransportWrapper(). User("myuser", "mypassword"). Build()
Note that some OpenID providers (Keycloak, for example) require the client identifier also for the resource owner password grant. In that case use the set only the identifier, and let the secret blank. For example:
// Use the resource owner password grant: wrapper, err := authentication.NewConnectionBuilder(). User("myuser", "mypassword"). Client("myclientid", ""). Build()
Note the empty client secret.