web/resource package implements a bearer-token resource server: RFC 6750
bearer-token extraction, JWT authentication (via the jwt package), an
RFC 7662 opaque-token introspection authenticator, a claims-to-Authentication
mapper, and the RequireBearer middleware with an RFC 6750
WWW-Authenticate challenge.
Import
JWT resource server
Build ajwt.Verifier and (optionally) a jwt.Validator, wrap them in a
BearerTokenAuthenticator, then pass that to RequireBearer:
RequireBearer(a TokenAuthenticator, opts ...BearerOption) returns a
middleware.Middleware (func(http.Handler) http.Handler), not an error —
apply it to your handler with a normal call, e.g.
resource.RequireBearer(tokenAuth)(apiHandler). It reads the
Authorization: Bearer <token> header, authenticates via the given
TokenAuthenticator, and stores the resulting Authentication on the
request context. It only authenticates: scope/role checks are layered after
it via authz route rules, so a missing/invalid token is a 401 and
insufficient scope is a 403.
BearerOptions: WithExceptionTranslation overrides the full 401/403
translation; WithEntryPoint overrides just the entry point (e.g. to set a
realm on BearerEntryPoint).
Claims mapping
NewBearerTokenAuthenticator(verifier, validator, mapper) takes a
ClaimsMapper that turns verified JWT claims into a core.Authentication. A
nil mapper defaults to DefaultClaimsMapper():
DefaultClaimsMapper() is ScopeAndRolesMapper(false):
- name =
subclaim (fallback:client_id, then empty) - authorities =
SCOPE_<x>for each entry of the space-delimitedscopeclaim (RFC 6749) or thescpclaim (string or array), plus the verbatim entries ofroles/authoritiesclaims - principal = a read-only value exposing
Subject()/Issuer()/Claims()(never the raw token)
ScopeAndRolesMapper(rolePrefix bool) lets you additionally wrap the
roles/authorities claim entries with core.RoleAuthority (ROLE_ prefix)
when rolePrefix is true. The SCOPE_ prefix on the scope/scp claim is
fixed — there is no option to change it. To customize mapping further, supply
your own ClaimsMapper (or ClaimsMapperFunc).
A JWT scope: "read" becomes authority "SCOPE_read", which you match with
HasAuthority(core.Authority("SCOPE_read")).
Opaque token introspection
For opaque tokens, build anIntrospectionAuthenticator against an RFC 7662
introspection endpoint — it satisfies the same TokenAuthenticator interface
as the JWT path, so it plugs into the same RequireBearer:
http://
requires the explicit AllowInsecureIntrospectionURL(true) option, for
localhost test fixtures only). An active: false (or missing) response is a
hard reject. The typed response fields (active, scope, client_id,
sub, iss, aud, exp) plus any extra fields are passed through the same
ClaimsMapper used for JWTs. Other options: WithIntrospectionHTTPClient,
WithIntrospectionMaxBytes.
Combining session and bearer authentication
For APIs that serve both browser clients (session) and machine clients (bearer token), scopeRequireBearer to the API prefix and let
securityhttp’s session handling cover the rest:
Error responses
A missing token gets a bare challenge; a present-but-invalid token addserror="invalid_token". There is no error_description — the response
never carries the underlying failure reason on the wire:
realm only appears if set via WithEntryPoint(resource.BearerEntryPoint{Realm: "..."}).)