Back to

Package oauth2

Latest Go to latest

The latest major version is .

Published: 2 days ago | License: MIT | Module:


Package oauth2 provides a middelware that introspects the auth token on behalf of PACE services and populate the request context with useful information when the token is valid, otherwise aborts the request.



r := mux.NewRouter()
middleware := Middleware{}


r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	userid, _ := UserID(r.Context())
	log.Printf("AUDIT: User %s does something", userid)

	if HasScope(r.Context(), "dtc:codes:write") {
		_, err := fmt.Fprintf(w, "User has scope.")
		if err != nil {
	_, err := fmt.Fprintf(w, "Your client may not have the right scopes to see the secret code")
	if err != nil {

srv := &http.Server{
	Handler: r,
	Addr:    "",

Example (MultipleBackends)


package main

import (


var _ oauth2.TokenIntrospecter = (*multiAuthBackends)(nil)

type multiAuthBackends []oauth2.TokenIntrospecter

func (b multiAuthBackends) IntrospectToken(ctx context.Context, token string) (resp *oauth2.IntrospectResponse, err error) {
	for _, backend := range b {
		resp, err = backend.IntrospectToken(ctx, token)
		if resp != nil && err == nil {
	return nil, oauth2.ErrInvalidToken

type authBackend [2]string

func (b *authBackend) IntrospectToken(ctx context.Context, token string) (*oauth2.IntrospectResponse, error) {
	if b[1] == token {
		return &oauth2.IntrospectResponse{
			Active:  true,
			Backend: b,
		}, nil
	return nil, oauth2.ErrInvalidToken

func main() {
	// In case you have multiple authorization backends, you can use the
	// oauth2.Backend(context.Context) function to retrieve the backend that
	// authorized the request. The actual value used for the backend depends on
	// your implementation: you can use constants or pointers, like in this
	// example.

	authorizer := oauth2.NewAuthorizer(multiAuthBackends{
		&authBackend{"A", "token-a"},
		&authBackend{"B", "token-b"},
		&authBackend{"C", "token-c"},
	}, nil)

	r := httptest.NewRequest("GET", "/some/endpoint", nil)
	r.Header.Set("Authorization", "Bearer token-b")

	if authorizer.CanAuthorizeRequest(r) {
		ctx, ok := authorizer.Authorize(r, nil)
		usedBackend, _ := oauth2.Backend(ctx)
		fmt.Printf("%t %s", ok, usedBackend.(*authBackend)[0])

true B




var ErrBadUpstreamResponse = errors.New("bad upstream response when introspecting token")

ErrBadUpstreamResponse the response from the server has the wrong format

var ErrInvalidToken = errors.New("user token is invalid")

ErrInvalidToken in case the token is not valid or expired

var ErrUpstreamConnection = errors.New("problem connecting to the introspection endpoint")

ErrUpstreamConnection connection issue

func Backend

func Backend(ctx context.Context) (interface{}, bool)

Backend returns the backend stored in the context. It identifies the authorization backend for the token.

func BearerToken

func BearerToken(ctx context.Context) (string, bool)

Deprecated: BearerToken was moved to the security package, because it's used by apiKey and oauth2 authorization. BearerToken returns the bearer token stored in ctx

func ClientID

func ClientID(ctx context.Context) (string, bool)

ClientID returns the clientID stored in ctx

func ContextTransfer

func ContextTransfer(sourceCtx context.Context, targetCtx context.Context) context.Context

ContextTransfer sources the oauth2 token from the sourceCtx and returning a new context based on the targetCtx

func HasScope

func HasScope(ctx context.Context, scope Scope) bool

HasScope extracts an access token from context and checks if the permissions represented by the provided scope are included in the valid scope.

func Request

func Request(r *http.Request) *http.Request

Request adds Authorization token to r

func Scopes

func Scopes(ctx context.Context) []string

Scopes returns the scopes stored in ctx

func UserID

func UserID(ctx context.Context) (string, bool)

UserID returns the userID stored in ctx

func WithBearerToken

func WithBearerToken(ctx context.Context, bearerToken string) context.Context

Deprecated: WithBearerToken was moved to the security package, because it's used by api key and oauth2 authorization. returns a new context with the given bearer token Use security.BearerToken() to retrieve the token. Use Request() to obtain a request with the Authorization header set accordingly.

type Authorizer

type Authorizer struct {
	// contains filtered or unexported fields

Authorizer is an implementation of security.Authorizer for OAuth2 it uses introspection to get user data and can check the scope

func NewAuthorizer

func NewAuthorizer(introspector TokenIntrospecter, cfg *Config) *Authorizer

NewAuthorizer creates an Authorizer for a specific TokenIntrospecter This Authorizer does not check the scope

func (*Authorizer) Authorize

func (a *Authorizer) Authorize(r *http.Request, w http.ResponseWriter) (context.Context, bool)

Authorize authorizes a request with an introspection and validates the scope Success: returns context with the introspection result and true Error: writes all errors directly to response, returns unchanged context and false

func (*Authorizer) CanAuthorizeRequest

func (a *Authorizer) CanAuthorizeRequest(r *http.Request) bool

CanAuthorizeRequest returns true, if the request contains a token in the configured header, otherwise false

func (*Authorizer) WithScope

func (a *Authorizer) WithScope(tok string) *Authorizer

WithScope returns a new Authorizer with the same TokenIntrospecter and the same Config that also checks the scope of a request

type Config

type Config struct {
	Description       string
	Implicit          *Flow
	Password          *Flow
	ClientCredentials *Flow
	AuthorizationCode *Flow

Config contains the configuration from the api definition - currently not used

type Flow

type Flow struct {
	AuthorizationURL string
	TokenURL         string
	RefreshURL       string
	Scopes           map[string]string

Flow is a part of the OAuth2 config from the security schema

type IntrospectResponse

type IntrospectResponse struct {
	Active   bool   `json:"active"`
	Scope    string `json:"scope"`
	ClientID string `json:"client_id"`
	UserID   string `json:"user_id"`

	// Backend identifies the backend used for introspection. This attribute
	// exists as a convenience if you have more than one authorization backend
	// and need to distinguish between those.
	Backend interface{} `json:"-"`

IntrospectResponse in case of a successful check of the oauth2 request

type Middleware

type Middleware struct {
	Backend TokenIntrospecter

Deprecated: Middleware holds data necessary for Oauth processing - Deprecated for generated apis, use the generated Authentication Backend of the API with oauth2.Authorizer

func NewMiddleware

func NewMiddleware(backend TokenIntrospecter) *Middleware

Deprecated: NewMiddleware creates a new Oauth middleware - Deprecated for generated apis, use the generated AuthenticationBackend of the API with oauth2.Authorizer

func (*Middleware) Handler

func (m *Middleware) Handler(next http.Handler) http.Handler

Handler will parse the bearer token, introspect it, and put the token and other relevant information back in the context.

type Scope

type Scope string

Scope represents an OAuth 2 access token scope

func (*Scope) IsIncludedIn

func (s *Scope) IsIncludedIn(t Scope) bool

IsIncludedIn checks if the permissions of a scope s are also included in the provided scope t. This can be useful to check if a scope has all required permissions to access an endpoint.

type TokenIntrospecter

type TokenIntrospecter interface {
	IntrospectToken(ctx context.Context, token string) (*IntrospectResponse, error)

TokenIntrospecter needs to be implemented for token lookup

Package Files

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier