Documentation ¶
Overview ¶
Authress is a lightweight package for adding token validation and introspection to resource servers. It supports OAuth2/OIDC discovery and custom keys & JWT parsing and validation the package also provides easily customizable and pluggable middleware for integrating authentication into net/http handlers.
See the README for usage and examples.
Index ¶
- Variables
- func RequireAuthJWT(v *Validator, opts ...MiddlewareOption) func(http.Handler) http.Handler
- func RequireAuthWithIntrospection(v *Validator, opts ...MiddlewareOption) func(http.Handler) http.Handler
- func SetAuthContextJWT(v *Validator, opts ...MiddlewareOption) func(http.Handler) http.Handler
- func SetAuthCtxhWithIntrospection(v *Validator, opts ...MiddlewareOption) func(http.Handler) http.Handler
- type AuthCtx
- type Claims
- func (c *Claims) ExpiresAtTime() time.Time
- func (c *Claims) GetClaim(key string) (any, bool)
- func (c *Claims) GetClaimAs(key string, v interface{}) error
- func (c *Claims) GetIntClaim(key string) int64
- func (c *Claims) GetStringClaim(key string) string
- func (c *Claims) IssuedAtTime() time.Time
- func (c *Claims) NotBeforeTime() time.Time
- func (c *Claims) Scopes() []string
- type ContextModifier
- type ErrorResponder
- type JWKSStore
- type MiddlewareOption
- type OAuth2ServerMetadata
- type Option
- func WithAudienceValidation(audience ...string) Option
- func WithDiscovery(discoveryUrl string) Option
- func WithHTTPClient(client *http.Client) Option
- func WithIntrospection(clientId, clientSecret string) Option
- func WithJWKS(jwks JWKSStore) Option
- func WithMetadata(metadata *OAuth2ServerMetadata) Option
- type Token
- type TokenExtractor
- type Validator
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidJWT = errors.New("token format is not valid") ErrInvalidSignature = errors.New("token format is not valid") ErrUnsupportedAlgorithm = errors.New("unsupported signing algorithm") ErrInvalidPublicKey = errors.New("invalid or unsupported public key") ErrInvalidIssuer = errors.New("invalid issuer") ErrTokenExpired = errors.New("token has expired") ErrTokenNotYetValid = errors.New("token is not yet valid; nbf > time.Now()") ErrInvalidAudience = errors.New("invalid audience claim") ErrCalimNotExists = errors.New("claim doesn't exist") ErrDiscoveryFailure = errors.New("failed to discover OAuth2 server metadata") )
var AuthContextKey = contextKey("x-authenticated")
AuthContextKey is the key used to store authentication information in the request context.
Functions ¶
func RequireAuthJWT ¶
RequireAuthJWT requires that a valid JWT is present in the request. If the JWT is invalid or missing, the request is rejected with HTTP 401 Unauthorized. If the JWT is valid, the parsed token is injected into the request context.
The JSON Web Token is extracted from the `Authorization` header using the Bearer scheme by default. You can customize the token extraction method using the WithTokenExtractor option, such as extracting the token from a cookie or a custom header.
if the JWT is valid, the request context is modified to include the parsed token and a flag indicating whether the request is authenticated. See the WithContextModifier option
If the token is invalid or missing, the middleware responds with a 401 status and a default "Unauthorized" message. The error response can be customized using WithErrorResponder option.
Example Usage:
requireJWT := RequireAuthJWT(validator) http.Handle("/secure", requireJWT(http.HandlerFunc(secureHandler))) http.ListenAndServe(":8080", nil) // Custom token extraction from a cookie and custom error response requireJWT := RequireAuthJWT(validator, WithTokenExtractor(func(r *http.Request) string { cookie, err := r.Cookie("token") if err != nil { return "" } return cookie.Value }), WithErrorResponder(func(w http.ResponseWriter, r *http.Request, err error) { http.Error(w, "Custom unauthorized message", http.StatusUnauthorized) }))
func RequireAuthWithIntrospection ¶
func RequireAuthWithIntrospection(v *Validator, opts ...MiddlewareOption) func(http.Handler) http.Handler
RequireAuthWithIntrospection requires a valid JWT by token introspection as defined by RFC 7662. Inrospection introduces network latency as it requires an HTTP roundtrip. useful for critical endpoints where ensuring that the token has not been revoked is important. In Most cases RequireAuthJWT middlware should be preferred
Example Usage:
requireAuth := RequireAuthWithIntrospection(introspectionValidator) http.Handle("/important", requireAuth(http.HandlerFunc(importantHandler))) http.ListenAndServe(":8080", nil)
func SetAuthContextJWT ¶
SetAuthContextJWT validates the JWT and injects the parsed token into the request context WITHOUT enforcing authentication. The Authentication decision is left to downstream middleware / handlers.
The JWT is extracted from the `Authorization` header using the Bearer scheme by default, See WithTokenExtractor option. You can modify how the context is updated using the WithContextModifier option.
Example Usage:
chain := alice.New(setAuthContextJWT, setAuthContextLDAP, enforceAuth, authorize).Then(http.HandlerFunc(secureHandler)) http.Handle("/secure", chain) http.ListenAndServe(":8080", nil)
func SetAuthCtxhWithIntrospection ¶
func SetAuthCtxhWithIntrospection(v *Validator, opts ...MiddlewareOption) func(http.Handler) http.Handler
SetAuthCtxWithIntrospection validates the token via introspection (RFC 7662) but DOES NOT ENFORCE authentication. It adds the token and its status to the context for downstream use.
Example:
v, err := authress.NewValidator( authress.WithAuthServerDiscovery(kcDiscoveryUrl), authress.WithIntrospection(clientID, clientSecret)) if err != nil { panic(err) // handle error } setAuthCtx := SetAuthCtxWithIntrospection(v) chain := alice.New(setAuthCtx, setContextLDAP, enforceAuth, authorize).Then(http.HandlerFunc(secureHandler)) http.Handle("/endpoint", chain) http.ListenAndServe(":8080", nil)
Types ¶
type Claims ¶ added in v0.1.1
type Claims struct { // Audience (aud) is the token's intended recipients. Audience audience `json:"aud"` // Issuer (iss) is the entity that issued the token. Issuer string `json:"iss"` // Subject (sub) is the principal the token is issued for. Subject string `json:"sub"` // ExpiresAt (exp) is the token's expiration time. ExpiresAt int64 `json:"exp"` // IssuedAt (iat) is when the token was issued. IssuedAt int64 `json:"iat"` // NotBefore (nbf) indicates when the token becomes valid. NotBefore int64 `json:"nbf"` // optional OIDC claim, zero value if absent Name string `json:"name"` // optional OIDC claim, zero value if absent GivenName string `json:"given_name"` // optional OIDC claim, zero value if absent FamilyName string `json:"family_name"` // optional OIDC claim, zero value if absent Email string `json:"email"` // optional OIDC claim, zero value if absent EmailVerified bool `json:"email_verified"` // optional OIDC claim, zero value if absent Picture string `json:"picture"` // optional OIDC claim, zero value if absent Scope string `json:"scope"` // contains filtered or unexported fields }
Claims represent JWT data. Registered claims (RFC 7519) and common OIDC claims are available as fields. Missing claims default to zero values Additional claims can be accessed lazily with Claims.GetClaim.
func (*Claims) ExpiresAtTime ¶ added in v0.1.1
ExpiresAtTime returns the `exp` time as time.Time
func (*Claims) GetClaimAs ¶ added in v0.1.1
GetClaimAs retrieves the claim by `key` and unmarshals it into `v`, which must be a non-nil pointer. It uses reflection to dynamically map the claim to the provided type.
This involves unmarshaling the raw JSON, which can be costly.
Returns an error if the key is empty or if `v` is not a valid pointer.
func (*Claims) GetIntClaim ¶ added in v0.1.1
GetIntClaim retrieves the value of a claim by its key as a int64. If the claim is missing or not numeric, zero returned.
func (*Claims) GetStringClaim ¶ added in v0.1.1
GetStringClaim retrieves the value of a claim by its key as a string. If the claim is missing or not a string, an empty string is returned.
func (*Claims) IssuedAtTime ¶ added in v0.1.1
IssuedAtTime returns the token's `iat` time as a time.Time
func (*Claims) NotBeforeTime ¶ added in v0.1.1
NotBeforeTime returns the token's `nbf` time as a time.Time
type ContextModifier ¶
ContextModifier modifies the request context, adding authentication details if the token is valid.
type ErrorResponder ¶
type ErrorResponder func(w http.ResponseWriter, r *http.Request, err error)
ErrorResponder handles the HTTP response when token validation fails (e.g., sending a 401 Unauthorized).
type MiddlewareOption ¶
type MiddlewareOption func(*middlewareOptions)
func WithContextModifier ¶
func WithContextModifier(modifier ContextModifier) MiddlewareOption
WithContextModifier sets a custom modifer of the request context
func WithErrorResponder ¶
func WithErrorResponder(responder ErrorResponder) MiddlewareOption
WithErrorResponder sets custom error response handling
func WithTokenExtractor ¶
func WithTokenExtractor(extractor TokenExtractor) MiddlewareOption
WithContextModifier sets custom JWT extractor from the request context based on authentication.
type OAuth2ServerMetadata ¶
type OAuth2ServerMetadata struct { Issuer string `json:"issuer"` AuthEndpoint string `json:"authorization_endpoint"` TokenEndpoint string `json:"token_endpoint"` DeviceAuthEndpoint string `json:"device_authorization_endpoint"` JWKURI string `json:"jwks_uri"` IntrospectionEndpoint string `json:"introspection_endpoint"` IntrospectionAuthMethodsSupported []string `json:"introspection_endpoint_auth_methods_supported"` RevocationEndpoint string `json:"revocation_endpoint"` RevocationAuthMethodsSupported []string `json:"revocation_endpoint_auth_methods_supported"` ScopesSupported []string `json:"scopes_supported"` ResponseTypesSupported []string `json:"response_types_supported"` GrantTypesSupported []string `json:"grant_types_supported"` TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported"` SubjectTypesSupported []string `json:"subject_types_supported"` IDTokenSigningAlgsSupported []string `json:"id_token_signing_alg_values_supported"` CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"` }
func (*OAuth2ServerMetadata) Endpoint ¶
func (m *OAuth2ServerMetadata) Endpoint() oauth2.Endpoint
type Option ¶
type Option func(*config)
func WithAudienceValidation ¶
WithAudienceValidation enables or disables audience validation and sets the expected audience.
func WithDiscovery ¶
func WithHTTPClient ¶
WithHTTPClient sets a custom HTTP client for fetching JWKS and introspection.
func WithIntrospection ¶
WithIntrospection enables token introspection.
func WithMetadata ¶
func WithMetadata(metadata *OAuth2ServerMetadata) Option
type TokenExtractor ¶
TokenExtractor extracts a token from the HTTP request (e.g., from a header or cookie).
func BearerTokenExtractor ¶
func BearerTokenExtractor() TokenExtractor
BearerTokenExtractor extracts the token from the Authorization header (Bearer token).
func CookieTokenExtractor ¶
func CookieTokenExtractor(cookieName string) TokenExtractor
CookieTokenExtractor extracts a token from a cookie.
func CustomHeaderTokenExtractor ¶
func CustomHeaderTokenExtractor(headerName string) TokenExtractor
CustomHeaderTokenExtractor extracts a token from a custom HTTP header.
type Validator ¶
type Validator struct {
// contains filtered or unexported fields
}
func (*Validator) ClientEndpoint ¶
ClientEndpoint return `x/oauth2` client Endpoint
func (*Validator) IntrospectToken ¶
IntrospectToken checks if the provided token is active by querying the introspection endpoint according to RFC 7662. Most users will prefer using Validator.ValidateJWT for local validation to avoid the network latency of introspection. Introspection is useful for opaque tokens or when you need to confirm if a token has been revoked.