The 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 a jwt.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 = sub claim (fallback: client_id, then empty)
  • authorities = SCOPE_<x> for each entry of the space-delimited scope claim (RFC 6749) or the scp claim (string or array), plus the verbatim entries of roles/authorities claims
  • 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 an IntrospectionAuthenticator against an RFC 7662 introspection endpoint — it satisfies the same TokenAuthenticator interface as the JWT path, so it plugs into the same RequireBearer:
The endpoint is called with HTTP Basic client credentials over TLS (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), scope RequireBearer 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 adds error="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: "..."}).)