op

package
v3.22.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2024 License: Apache-2.0 Imports: 35 Imported by: 15

Documentation

Index

Examples

Constants

View Source
const (
	CharSetBase20 = "BCDFGHJKLMNPQRSTVWXZ"
	CharSetDigits = "0123456789"
)
View Source
const RecommendedDeviceCodeBytes = 16

16 bytes gives 128 bit of entropy. results in a 22 character base64 encoded string.

Variables

View Source
var (
	ErrInvalidAuthHeader   = errors.New("invalid basic auth header")
	ErrNoClientCredentials = errors.New("no client credentials provided")
	ErrMissingClientID     = errors.New("client_id missing from request")
)
View Source
var (
	ErrInvalidIssuerPath        = errors.New("no fragments or query allowed for issuer")
	ErrInvalidIssuerNoIssuer    = errors.New("missing issuer")
	ErrInvalidIssuerURL         = errors.New("invalid url for issuer")
	ErrInvalidIssuerMissingHost = errors.New("host for issuer missing")
	ErrInvalidIssuerHTTPS       = errors.New("scheme for issuer must be `https`")
)
View Source
var (
	UserCodeBase20 = UserCodeConfig{
		CharSet:      CharSetBase20,
		CharAmount:   8,
		DashInterval: 4,
	}
	UserCodeDigits = UserCodeConfig{
		CharSet:      CharSetDigits,
		CharAmount:   9,
		DashInterval: 3,
	}
)
View Source
var (
	DefaultEndpoints = &Endpoints{
		Authorization:       NewEndpoint(defaultAuthorizationEndpoint),
		Token:               NewEndpoint(defaultTokenEndpoint),
		Introspection:       NewEndpoint(defaultIntrospectEndpoint),
		Userinfo:            NewEndpoint(defaultUserinfoEndpoint),
		Revocation:          NewEndpoint(defaultRevocationEndpoint),
		EndSession:          NewEndpoint(defaultEndSessionEndpoint),
		JwksURI:             NewEndpoint(defaultKeysEndpoint),
		DeviceAuthorization: NewEndpoint(defaultDeviceAuthzEndpoint),
	}

	DefaultSupportedClaims = []string{
		"sub",
		"aud",
		"exp",
		"iat",
		"iss",
		"auth_time",
		"nonce",
		"acr",
		"amr",
		"c_hash",
		"at_hash",
		"act",
		"scopes",
		"client_id",
		"azp",
		"preferred_username",
		"name",
		"family_name",
		"given_name",
		"locale",
		"email",
		"email_verified",
		"phone_number",
		"phone_number_verified",
	}
)
View Source
var (
	ErrAuthReqMissingClientID    = errors.New("auth request is missing client_id")
	ErrAuthReqMissingRedirectURI = errors.New("auth request is missing redirect_uri")
)
View Source
var ErrDuplicateUserCode = errors.New("user code already exists")
View Source
var ErrInvalidRefreshToken = errors.New("invalid_refresh_token")
View Source
var ErrNilEndpoint = errors.New("nil endpoint")
View Source
var ErrSignerCreationFailed = errors.New("signer creation failed")
View Source
var UnimplementedStatusCode = http.StatusNotFound

UnimplementedStatusCode is the status code returned for methods that are not yet implemented. Note that this means methods in the sense of the Go interface, and not http methods covered by "501 Not Implemented".

Functions

func AccessTokenTypeStrings

func AccessTokenTypeStrings() []string

AccessTokenTypeStrings returns a slice of all String values of the enum

func ApplicationTypeStrings

func ApplicationTypeStrings() []string

ApplicationTypeStrings returns a slice of all String values of the enum

func AuthCallbackURL

func AuthCallbackURL(o OpenIDProvider) func(context.Context, string) string

AuthCallbackURL builds the url for the redirect (with the requestID) after a successful login

func AuthMethodsIntrospectionEndpoint

func AuthMethodsIntrospectionEndpoint(c Configuration) []oidc.AuthMethod

func AuthMethodsRevocationEndpoint

func AuthMethodsRevocationEndpoint(c Configuration) []oidc.AuthMethod

func AuthMethodsTokenEndpoint

func AuthMethodsTokenEndpoint(c Configuration) []oidc.AuthMethod

func AuthRequestError

func AuthRequestError(w http.ResponseWriter, r *http.Request, authReq ErrAuthRequest, err error, authorizer Authorizer)

func AuthResponse

func AuthResponse(authReq AuthRequest, authorizer Authorizer, w http.ResponseWriter, r *http.Request)

AuthResponse creates the successful authentication response (either code or tokens)

func AuthResponseCode

func AuthResponseCode(w http.ResponseWriter, r *http.Request, authReq AuthRequest, authorizer Authorizer)

AuthResponseCode creates the successful code authentication response

func AuthResponseFormPost added in v3.14.0

func AuthResponseFormPost(res http.ResponseWriter, redirectURI string, response any, encoder httphelper.Encoder) error

AuthResponseFormPost responds a html page that automatically submits the form which contains the auth response parameters

func AuthResponseToken

func AuthResponseToken(w http.ResponseWriter, r *http.Request, authReq AuthRequest, authorizer Authorizer, client Client)

AuthResponseToken creates the successful token(s) authentication response

func AuthResponseURL

func AuthResponseURL(redirectURI string, responseType oidc.ResponseType, responseMode oidc.ResponseMode, response any, encoder httphelper.Encoder) (string, error)

AuthResponseURL encodes the authorization response (successful and error) and sets it as query or fragment values depending on the response_mode and response_type

func Authorize

func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer)

Authorize handles the authorization request, including parsing, validating, storing and finally redirecting to the login handler

func AuthorizeCallback

func AuthorizeCallback(w http.ResponseWriter, r *http.Request, authorizer Authorizer)

AuthorizeCallback handles the callback after authentication in the Login UI

func AuthorizeClientIDSecret

func AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string, storage Storage) error

AuthorizeClientIDSecret authorizes a client by validating the client_id and client_secret (Basic Auth and POST)

func AuthorizeCodeChallenge

func AuthorizeCodeChallenge(codeVerifier string, challenge *oidc.CodeChallenge) error

AuthorizeCodeChallenge authorizes a client by validating the code_verifier against the previously sent code_challenge of the auth request (PKCE)

func AuthorizeCodeClient

func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, exchanger Exchanger) (request AuthRequest, client Client, err error)

AuthorizeCodeClient checks the authorization of the client and that the used method was the one previously registered. It than returns the auth request corresponding to the auth code

func AuthorizeRefreshClient

func AuthorizeRefreshClient(ctx context.Context, tokenReq *oidc.RefreshTokenRequest, exchanger Exchanger) (request RefreshTokenRequest, client Client, err error)

AuthorizeRefreshClient checks the authorization of the client and that the used method was the one previously registered. It than returns the data representing the original auth request corresponding to the refresh_token

func BuildAuthRequestCode

func BuildAuthRequestCode(authReq AuthRequest, crypto Crypto) (string, error)

BuildAuthRequestCode builds the string representation of the auth code

func ClientBasicAuth

func ClientBasicAuth(r *http.Request, storage Storage) (clientID string, err error)

func ClientCredentialsExchange

func ClientCredentialsExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger)

ClientCredentialsExchange handles the OAuth 2.0 client_credentials grant, including parsing, validating, authorizing the client and finally returning a token

func ClientIDFromRequest

func ClientIDFromRequest(r *http.Request, p ClientProvider) (clientID string, authenticated bool, err error)

ClientIDFromRequest parses the request form and tries to obtain the client ID and reports if it is authenticated, using a JWT or static client secrets over http basic auth.

If the Provider implements IntrospectorJWTProfile and "client_assertion" is present in the form data, JWT assertion will be verified and the client ID is taken from there. If any of them is absent, basic auth is attempted. In absence of basic auth data, the unauthenticated client id from the form data is returned.

If no client id can be obtained by any method, oidc.ErrInvalidClient is returned with ErrMissingClientID wrapped in it.

func ClientJWTAuth

func ClientJWTAuth(ctx context.Context, ca oidc.ClientAssertionParams, verifier ClientJWTProfile) (clientID string, err error)

func CodeChallengeMethods

func CodeChallengeMethods(c Configuration) []oidc.CodeChallengeMethod

func CodeExchange

func CodeExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger)

CodeExchange handles the OAuth 2.0 authorization_code grant, including parsing, validating, authorizing the client and finally exchanging the code for tokens

func ContainsResponseType

func ContainsResponseType(types []oidc.ResponseType, responseType oidc.ResponseType) bool

func ContextWithIssuer

func ContextWithIssuer(ctx context.Context, issuer string) context.Context

ContextWithIssuer returns a new context with issuer set to it.

func CopyRequestObjectToAuthRequest

func CopyRequestObjectToAuthRequest(authReq *oidc.AuthRequest, requestObject *oidc.RequestObject)

CopyRequestObjectToAuthRequest overwrites present values from the Request Object into the auth request and clears the `RequestParam` of the auth request

func CreateAccessToken

func CreateAccessToken(ctx context.Context, tokenRequest TokenRequest, accessTokenType AccessTokenType, creator TokenCreator, client AccessTokenClient, refreshToken string) (accessToken, newRefreshToken string, validity time.Duration, err error)

func CreateAuthRequestCode

func CreateAuthRequestCode(ctx context.Context, authReq AuthRequest, storage Storage, crypto Crypto) (string, error)

CreateAuthRequestCode creates and stores a code for the auth code response

func CreateBearerToken

func CreateBearerToken(tokenID, subject string, crypto Crypto) (string, error)

func CreateClientCredentialsTokenResponse

func CreateClientCredentialsTokenResponse(ctx context.Context, tokenRequest TokenRequest, creator TokenCreator, client Client) (*oidc.AccessTokenResponse, error)

func CreateDeviceTokenResponse

func CreateDeviceTokenResponse(ctx context.Context, tokenRequest TokenRequest, creator TokenCreator, client Client) (*oidc.AccessTokenResponse, error)

func CreateDiscoveryConfig

func CreateDiscoveryConfig(ctx context.Context, config Configuration, storage DiscoverStorage) *oidc.DiscoveryConfiguration

func CreateIDToken

func CreateIDToken(ctx context.Context, issuer string, request IDTokenRequest, validity time.Duration, accessToken, code string, storage Storage, client Client) (string, error)

func CreateJWT

func CreateJWT(ctx context.Context, issuer string, tokenRequest TokenRequest, exp time.Time, id string, client AccessTokenClient, storage Storage) (string, error)

func CreateJWTTokenResponse

func CreateJWTTokenResponse(ctx context.Context, tokenRequest TokenRequest, creator TokenCreator) (*oidc.AccessTokenResponse, error)

CreateJWTTokenResponse creates an access_token response for a JWT Profile Grant request by default the access_token is an opaque string, but can be specified by implementing the JWTProfileTokenStorage interface

func CreateRouter

func CreateRouter(o OpenIDProvider, interceptors ...HttpInterceptor) chi.Router

func CreateTokenExchangeResponse

func CreateTokenExchangeResponse(
	ctx context.Context,
	tokenExchangeRequest TokenExchangeRequest,
	client Client,
	creator TokenCreator,
) (_ *oidc.TokenExchangeResponse, err error)

func CreateTokenResponse

func CreateTokenResponse(ctx context.Context, request IDTokenRequest, client Client, creator TokenCreator, createAccessToken bool, code, refreshToken string) (*oidc.AccessTokenResponse, error)

func DeviceAccessToken

func DeviceAccessToken(w http.ResponseWriter, r *http.Request, exchanger Exchanger)

func DeviceAuthorization

func DeviceAuthorization(w http.ResponseWriter, r *http.Request, o OpenIDProvider) error

func DeviceAuthorizationHandler

func DeviceAuthorizationHandler(o OpenIDProvider) func(http.ResponseWriter, *http.Request)

func Discover

func Discover(w http.ResponseWriter, config *oidc.DiscoveryConfiguration)

func EndSession

func EndSession(w http.ResponseWriter, r *http.Request, ender SessionEnder)

func Exchange

func Exchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger)

Exchange performs a token exchange appropriate for the grant type

func GetTokenIDAndSubjectFromToken

func GetTokenIDAndSubjectFromToken(
	ctx context.Context,
	exchanger Exchanger,
	token string,
	tokenType oidc.TokenType,
	isActor bool,
) (tokenIDOrToken, subject string, claims map[string]any, ok bool)

func GrantTypes

func GrantTypes(c Configuration) []oidc.GrantType

func HTTPLoopbackOrLocalhost

func HTTPLoopbackOrLocalhost(rawURL string) (*url.URL, bool)

func Introspect

func Introspect(w http.ResponseWriter, r *http.Request, introspector Introspector)

func IntrospectionSigAlgorithms

func IntrospectionSigAlgorithms(c Configuration) []string

func IsConfidentialType

func IsConfidentialType(c Client) bool

func IssuerFromContext

func IssuerFromContext(ctx context.Context) string

IssuerFromContext reads the issuer from the context (set by an IssuerInterceptor) it will return an empty string if not found

func IssuerFromForwardedOrHost

func IssuerFromForwardedOrHost(path string, opts ...IssuerFromOption) func(bool) (IssuerFromRequest, error)

IssuerFromForwardedOrHost tries to establish the Issuer based on the Forwarded header host field. If multiple Forwarded headers are present, the first mention of the host field will be used. If the Forwarded header is not present, no host field is found, or there is a parser error the Request Host will be used as a fallback. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded

func IssuerFromHost

func IssuerFromHost(path string) func(bool) (IssuerFromRequest, error)

func JWTProfile

func JWTProfile(w http.ResponseWriter, r *http.Request, exchanger JWTAuthorizationGrantExchanger)

JWTProfile handles the OAuth 2.0 JWT Profile Authorization Grant https://tools.ietf.org/html/rfc7523#section-2.1

func Keys

func NewDeviceCode

func NewDeviceCode(nBytes int) (string, error)

func NewUserCode

func NewUserCode(charSet []rune, charAmount, dashInterval int) (string, error)

func ParseAccessTokenRequest

func ParseAccessTokenRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.AccessTokenRequest, error)

ParseAccessTokenRequest parsed the http request into a oidc.AccessTokenRequest

func ParseAuthenticatedTokenRequest

func ParseAuthenticatedTokenRequest(r *http.Request, decoder httphelper.Decoder, request AuthenticatedTokenRequest) error

ParseAuthenticatedTokenRequest parses the client_id and client_secret from the HTTP request from either HTTP Basic Auth header or form body and sets them into the provided authenticatedTokenRequest interface

func ParseAuthorizeCallbackRequest

func ParseAuthorizeCallbackRequest(r *http.Request) (id string, err error)

func ParseAuthorizeRequest

func ParseAuthorizeRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.AuthRequest, error)

ParseAuthorizeRequest parsed the http request into an oidc.AuthRequest

func ParseClientCredentialsRequest

func ParseClientCredentialsRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.ClientCredentialsRequest, error)

ParseClientCredentialsRequest parsed the http request into a oidc.ClientCredentialsRequest

func ParseDeviceAccessTokenRequest

func ParseDeviceAccessTokenRequest(r *http.Request, exchanger Exchanger) (*oidc.DeviceAccessTokenRequest, error)

func ParseEndSessionRequest

func ParseEndSessionRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.EndSessionRequest, error)

func ParseJWTProfileGrantRequest

func ParseJWTProfileGrantRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.JWTProfileGrantRequest, error)

func ParseJWTProfileRequest

func ParseJWTProfileRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.JWTProfileGrantRequest, error)

ParseJWTProfileRequest has been renamed to ParseJWTProfileGrantRequest

deprecated: use ParseJWTProfileGrantRequest

func ParseRefreshTokenRequest

func ParseRefreshTokenRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.RefreshTokenRequest, error)

ParseRefreshTokenRequest parsed the http request into a oidc.RefreshTokenRequest

func ParseRequestObject

func ParseRequestObject(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, issuer string) error

ParseRequestObject parse the `request` parameter, validates the token including the signature and copies the token claims into the auth request

func ParseTokenExchangeRequest

func ParseTokenExchangeRequest(r *http.Request, decoder httphelper.Decoder) (_ *oidc.TokenExchangeRequest, clientID, clientSecret string, err error)

ParseTokenExchangeRequest parses the http request into oidc.TokenExchangeRequest

func ParseTokenIntrospectionRequest

func ParseTokenIntrospectionRequest(r *http.Request, introspector Introspector) (token, clientID string, err error)

func ParseTokenRevocationRequest

func ParseTokenRevocationRequest(r *http.Request, revoker Revoker) (token, tokenTypeHint, clientID string, err error)

func ParseUserinfoRequest

func ParseUserinfoRequest(r *http.Request, decoder httphelper.Decoder) (string, error)

func Readiness

func Readiness(w http.ResponseWriter, r *http.Request, probes ...ProbesFn)

func RedirectToLogin

func RedirectToLogin(authReqID string, client Client, w http.ResponseWriter, r *http.Request)

RedirectToLogin redirects the end user to the Login UI for authentication

func RefreshTokenExchange

func RefreshTokenExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger)

RefreshTokenExchange handles the OAuth 2.0 refresh_token grant, including parsing, validating, authorizing the client and finally exchanging the refresh_token for new tokens

func RegisterLegacyServer added in v3.1.0

func RegisterLegacyServer(s ExtendedLegacyServer, options ...ServerOption) http.Handler

RegisterLegacyServer registers a LegacyServer or an extension thereof. It takes care of registering the IssuerFromRequest middleware and Authorization Callback Routes. Neither are part of the bare Server interface.

EXPERIMENTAL: may change until v4

func RegisterServer

func RegisterServer(server Server, endpoints Endpoints, options ...ServerOption) http.Handler

RegisterServer registers an implementation of Server. The resulting handler takes care of routing and request parsing, with some basic validation of required fields. The routes can be customized with [WithEndpoints].

EXPERIMENTAL: may change until v4

func RequestError

func RequestError(w http.ResponseWriter, r *http.Request, err error, logger *slog.Logger)

func RequestObjectSigAlgorithms

func RequestObjectSigAlgorithms(c Configuration) []string

func ResponseTypes

func ResponseTypes(c Configuration) []string

func RevocationRequestError

func RevocationRequestError(w http.ResponseWriter, r *http.Request, err error)

func RevocationSigAlgorithms

func RevocationSigAlgorithms(c Configuration) []string

func Revoke

func Revoke(w http.ResponseWriter, r *http.Request, revoker Revoker)

func Scopes

func Scopes(c Configuration) []string

func SigAlgorithms

func SigAlgorithms(ctx context.Context, storage DiscoverStorage) []string

func SignerFromKey

func SignerFromKey(key SigningKey) (jose.Signer, error)

func StaticIssuer

func StaticIssuer(issuer string) func(bool) (IssuerFromRequest, error)

func SubjectIsIssuer

func SubjectIsIssuer(request *oidc.JWTTokenRequest) error

SubjectIsIssuer

func SubjectTypes

func SubjectTypes(c Configuration) []string

func SupportedClaims

func SupportedClaims(c Configuration) []string

func TokenExchange

func TokenExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger)

TokenExchange handles the OAuth 2.0 token exchange grant ("urn:ietf:params:oauth:grant-type:token-exchange")

func TokenSigAlgorithms

func TokenSigAlgorithms(c Configuration) []string

func Userinfo

func Userinfo(w http.ResponseWriter, r *http.Request, userinfoProvider UserinfoProvider)

func ValidateAccessTokenRequest

func ValidateAccessTokenRequest(ctx context.Context, tokenReq *oidc.AccessTokenRequest, exchanger Exchanger) (AuthRequest, Client, error)

ValidateAccessTokenRequest validates the token request parameters including authorization check of the client and returns the previous created auth request corresponding to the auth code

func ValidateAuthReqIDTokenHint

func ValidateAuthReqIDTokenHint(ctx context.Context, idTokenHint string, verifier *IDTokenHintVerifier) (string, error)

ValidateAuthReqIDTokenHint validates the id_token_hint (if passed as parameter in the request) and returns the `sub` claim

func ValidateAuthReqPrompt

func ValidateAuthReqPrompt(prompts []string, maxAge *uint) (_ *uint, err error)

ValidateAuthReqPrompt validates the passed prompt values and sets max_age to 0 if prompt login is present

func ValidateAuthReqRedirectURI

func ValidateAuthReqRedirectURI(client Client, uri string, responseType oidc.ResponseType) error

ValidateAuthReqRedirectURI validates the passed redirect_uri and response_type to the registered uris and client type

func ValidateAuthReqResponseType

func ValidateAuthReqResponseType(client Client, responseType oidc.ResponseType) error

ValidateAuthReqResponseType validates the passed response_type to the registered response types

func ValidateAuthReqScopes

func ValidateAuthReqScopes(client Client, scopes []string) ([]string, error)

ValidateAuthReqScopes validates the passed scopes

func ValidateAuthRequest

func ValidateAuthRequest(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, verifier *IDTokenHintVerifier) (sub string, err error)

ValidateAuthRequest validates the authorize parameters and returns the userID of the id_token_hint if passed

func ValidateClientCredentialsRequest

func ValidateClientCredentialsRequest(ctx context.Context, request *oidc.ClientCredentialsRequest, exchanger Exchanger) (TokenRequest, Client, error)

ValidateClientCredentialsRequest validates the client_credentials request parameters including authorization check of the client and returns a TokenRequest and Client implementation to be used in the client_credentials response, resp. creation of the corresponding access_token.

func ValidateEndSessionPostLogoutRedirectURI

func ValidateEndSessionPostLogoutRedirectURI(postLogoutRedirectURI string, client Client) error

func ValidateGrantType

func ValidateGrantType(client interface{ GrantTypes() []oidc.GrantType }, grantType oidc.GrantType) bool

ValidateGrantType ensures that the requested grant_type is allowed by the client

func ValidateIssuer

func ValidateIssuer(issuer string, allowInsecure bool) error

func ValidateIssuerPath

func ValidateIssuerPath(issuer *url.URL) error

func ValidateRefreshTokenRequest

func ValidateRefreshTokenRequest(ctx context.Context, tokenReq *oidc.RefreshTokenRequest, exchanger Exchanger) (RefreshTokenRequest, Client, error)

ValidateRefreshTokenRequest validates the refresh_token request parameters including authorization check of the client and returns the data representing the original auth request corresponding to the refresh_token

func ValidateRefreshTokenScopes

func ValidateRefreshTokenScopes(requestedScopes []string, authRequest RefreshTokenRequest) error

ValidateRefreshTokenScopes validates that the requested scope is a subset of the original auth request scope it will set the requested scopes as current scopes onto RefreshTokenRequest if empty the original scopes will be used

func ValidateTokenExchangeRequest

func ValidateTokenExchangeRequest(
	ctx context.Context,
	oidcTokenExchangeRequest *oidc.TokenExchangeRequest,
	clientID, clientSecret string,
	exchanger Exchanger,
) (TokenExchangeRequest, Client, error)

ValidateTokenExchangeRequest validates the token exchange request parameters including authorization check of the client, subject_token and actor_token

func VerifyAccessToken

func VerifyAccessToken[C oidc.Claims](ctx context.Context, token string, v *AccessTokenVerifier) (claims C, err error)

VerifyAccessToken validates the access token (issuer, signature and expiration).

Example (CustomClaims)
package main

import (
	"context"
	"fmt"

	tu "github.com/zitadel/oidc/v3/internal/testutil"
	"github.com/zitadel/oidc/v3/pkg/oidc"
	"github.com/zitadel/oidc/v3/pkg/op"
)

// MyCustomClaims extends the TokenClaims base,
// so it implements the oidc.Claims interface.
// Instead of carrying a map, we add needed fields// to the struct for type safe access.
type MyCustomClaims struct {
	oidc.TokenClaims
	NotBefore            oidc.Time `json:"nbf,omitempty"`
	CodeHash             string    `json:"c_hash,omitempty"`
	SessionID            string    `json:"sid,omitempty"`
	Scopes               []string  `json:"scope,omitempty"`
	AccessTokenUseNumber int       `json:"at_use_nbr,omitempty"`
	Foo                  string    `json:"foo,omitempty"`
	Bar                  *Nested   `json:"bar,omitempty"`
}

// Nested struct types are also possible.
type Nested struct {
	Count int      `json:"count,omitempty"`
	Tags  []string `json:"tags,omitempty"`
}

/*
accessToken carries the following claims. foo and bar are custom claims

	{
		"aud": [
			"unit",
			"test"
		],
		"bar": {
			"count": 22,
			"tags": [
				"some",
				"tags"
			]
		},
		"exp": 4802234675,
		"foo": "Hello, World!",
		"iat": 1678097014,
		"iss": "local.com",
		"jti": "9876",
		"nbf": 1678097014,
		"sub": "tim@local.com"
	}
*/
const accessToken = `eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJhdWQiOlsidW5pdCIsInRlc3QiXSwiYmFyIjp7ImNvdW50IjoyMiwidGFncyI6WyJzb21lIiwidGFncyJdfSwiZXhwIjo0ODAyMjM0Njc1LCJmb28iOiJIZWxsbywgV29ybGQhIiwiaWF0IjoxNjc4MDk3MDE0LCJpc3MiOiJsb2NhbC5jb20iLCJqdGkiOiI5ODc2IiwibmJmIjoxNjc4MDk3MDE0LCJzdWIiOiJ0aW1AbG9jYWwuY29tIn0.OUgk-B7OXjYlYFj-nogqSDJiQE19tPrbzqUHEAjcEiJkaWo6-IpGVfDiGKm-TxjXQsNScxpaY0Pg3XIh1xK6TgtfYtoLQm-5RYw_mXgb9xqZB2VgPs6nNEYFUDM513MOU0EBc0QMyqAEGzW-HiSPAb4ugCvkLtM1yo11Xyy6vksAdZNs_mJDT4X3vFXnr0jk0ugnAW6fTN3_voC0F_9HQUAkmd750OIxkAHxAMvEPQcpbLHenVvX_Q0QMrzClVrxehn5TVMfmkYYg7ocr876Bq9xQGPNHAcrwvVIJqdg5uMUA38L3HC2BEueG6furZGvc7-qDWAT1VR9liM5ieKpPg`

func main() {
	v := op.NewAccessTokenVerifier("local.com", tu.KeySet{})

	// VerifyAccessToken can be called with the *MyCustomClaims.
	claims, err := op.VerifyAccessToken[*MyCustomClaims](context.TODO(), accessToken, v)
	if err != nil {
		panic(err)
	}

	// Here we have typesafe access to the custom claims
	fmt.Println(claims.Foo, claims.Bar.Count, claims.Bar.Tags)
}
Output:

Hello, World! 22 [some tags]

func VerifyIDTokenHint

func VerifyIDTokenHint[C oidc.Claims](ctx context.Context, token string, v *IDTokenHintVerifier) (claims C, err error)

VerifyIDTokenHint validates the id token according to https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. In case of an expired token both the Claims and first encountered expiry related error is returned of type IDTokenHintExpiredError. In that case the caller can choose to still trust the token for cases like logout, as signature and other verifications succeeded.

func VerifyJWTAssertion

func VerifyJWTAssertion(ctx context.Context, assertion string, v *JWTProfileVerifier) (*oidc.JWTTokenRequest, error)

VerifyJWTAssertion verifies the assertion string from JWT Profile (authorization grant and client authentication)

checks audience, exp, iat, signature and that issuer and sub are the same

func WriteError

func WriteError(w http.ResponseWriter, r *http.Request, err error, logger *slog.Logger)

WriteError asserts for a StatusError containing an oidc.Error. If no `StatusError` is found, the status code will default to http.StatusBadRequest. If no `oidc.Error` was found in the parent, the error type defaults to oidc.ServerError. When there was no `StatusError` and the `oidc.Error` is of type `oidc.ServerError`, the status code will be set to http.StatusInternalServerError

Types

type AccessTokenClient

type AccessTokenClient interface {
	GetID() string
	ClockSkew() time.Duration
	RestrictAdditionalAccessTokenScopes() func(scopes []string) []string
	GrantTypes() []oidc.GrantType
}

type AccessTokenType

type AccessTokenType int
const (
	AccessTokenTypeBearer AccessTokenType = iota // bearer
	AccessTokenTypeJWT                           // JWT
)

func AccessTokenTypeString

func AccessTokenTypeString(s string) (AccessTokenType, error)

AccessTokenTypeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func AccessTokenTypeValues

func AccessTokenTypeValues() []AccessTokenType

AccessTokenTypeValues returns all values of the enum

func (AccessTokenType) IsAAccessTokenType

func (i AccessTokenType) IsAAccessTokenType() bool

IsAAccessTokenType returns "true" if the value is listed in the enum definition. "false" otherwise

func (AccessTokenType) MarshalGQL

func (i AccessTokenType) MarshalGQL(w io.Writer)

MarshalGQL implements the graphql.Marshaler interface for AccessTokenType

func (AccessTokenType) MarshalJSON

func (i AccessTokenType) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for AccessTokenType

func (AccessTokenType) MarshalText

func (i AccessTokenType) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface for AccessTokenType

func (AccessTokenType) MarshalYAML

func (i AccessTokenType) MarshalYAML() (interface{}, error)

MarshalYAML implements a YAML Marshaler for AccessTokenType

func (*AccessTokenType) Scan

func (i *AccessTokenType) Scan(value interface{}) error

func (AccessTokenType) String

func (i AccessTokenType) String() string

func (*AccessTokenType) UnmarshalGQL

func (i *AccessTokenType) UnmarshalGQL(value interface{}) error

UnmarshalGQL implements the graphql.Unmarshaler interface for AccessTokenType

func (*AccessTokenType) UnmarshalJSON

func (i *AccessTokenType) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for AccessTokenType

func (*AccessTokenType) UnmarshalText

func (i *AccessTokenType) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface for AccessTokenType

func (*AccessTokenType) UnmarshalYAML

func (i *AccessTokenType) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements a YAML Unmarshaler for AccessTokenType

func (AccessTokenType) Value

func (i AccessTokenType) Value() (driver.Value, error)

type AccessTokenVerifier

type AccessTokenVerifier oidc.Verifier

func NewAccessTokenVerifier

func NewAccessTokenVerifier(issuer string, keySet oidc.KeySet, opts ...AccessTokenVerifierOpt) *AccessTokenVerifier

NewAccessTokenVerifier returns a AccessTokenVerifier suitable for access token verification.

type AccessTokenVerifierOpt

type AccessTokenVerifierOpt func(*AccessTokenVerifier)

func WithSupportedAccessTokenSigningAlgorithms

func WithSupportedAccessTokenSigningAlgorithms(algs ...string) AccessTokenVerifierOpt

type ApplicationType

type ApplicationType int
const (
	ApplicationTypeWeb       ApplicationType = iota // web
	ApplicationTypeUserAgent                        // user_agent
	ApplicationTypeNative                           // native
)

func ApplicationTypeString

func ApplicationTypeString(s string) (ApplicationType, error)

ApplicationTypeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func ApplicationTypeValues

func ApplicationTypeValues() []ApplicationType

ApplicationTypeValues returns all values of the enum

func (ApplicationType) IsAApplicationType

func (i ApplicationType) IsAApplicationType() bool

IsAApplicationType returns "true" if the value is listed in the enum definition. "false" otherwise

func (ApplicationType) MarshalGQL

func (i ApplicationType) MarshalGQL(w io.Writer)

MarshalGQL implements the graphql.Marshaler interface for ApplicationType

func (ApplicationType) MarshalJSON

func (i ApplicationType) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for ApplicationType

func (ApplicationType) MarshalText

func (i ApplicationType) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface for ApplicationType

func (ApplicationType) MarshalYAML

func (i ApplicationType) MarshalYAML() (interface{}, error)

MarshalYAML implements a YAML Marshaler for ApplicationType

func (*ApplicationType) Scan

func (i *ApplicationType) Scan(value interface{}) error

func (ApplicationType) String

func (i ApplicationType) String() string

func (*ApplicationType) UnmarshalGQL

func (i *ApplicationType) UnmarshalGQL(value interface{}) error

UnmarshalGQL implements the graphql.Unmarshaler interface for ApplicationType

func (*ApplicationType) UnmarshalJSON

func (i *ApplicationType) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for ApplicationType

func (*ApplicationType) UnmarshalText

func (i *ApplicationType) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface for ApplicationType

func (*ApplicationType) UnmarshalYAML

func (i *ApplicationType) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements a YAML Unmarshaler for ApplicationType

func (ApplicationType) Value

func (i ApplicationType) Value() (driver.Value, error)

type AuthMethod

type AuthMethod string

type AuthRequest

type AuthRequest interface {
	GetID() string
	GetACR() string
	GetAMR() []string
	GetAudience() []string
	GetAuthTime() time.Time
	GetClientID() string
	GetCodeChallenge() *oidc.CodeChallenge
	GetNonce() string
	GetRedirectURI() string
	GetResponseType() oidc.ResponseType
	GetResponseMode() oidc.ResponseMode
	GetScopes() []string
	GetState() string
	GetSubject() string
	Done() bool
}

func AuthRequestByCode

func AuthRequestByCode(ctx context.Context, storage Storage, code string) (AuthRequest, error)

AuthRequestByCode returns the AuthRequest previously created from Storage corresponding to the auth code or an error

type AuthStorage

type AuthStorage interface {
	CreateAuthRequest(context.Context, *oidc.AuthRequest, string) (AuthRequest, error)
	AuthRequestByID(context.Context, string) (AuthRequest, error)
	AuthRequestByCode(context.Context, string) (AuthRequest, error)
	SaveAuthCode(context.Context, string, string) error
	DeleteAuthRequest(context.Context, string) error

	// The TokenRequest parameter of CreateAccessToken can be any of:
	//
	// * TokenRequest as returned by ClientCredentialsStorage.ClientCredentialsTokenRequest,
	//
	// * AuthRequest as returned by AuthRequestByID or AuthRequestByCode (above)
	//
	// * *oidc.JWTTokenRequest from a JWT that is the assertion value of a JWT Profile
	//   Grant: https://datatracker.ietf.org/doc/html/rfc7523#section-2.1
	//
	// * TokenExchangeRequest as returned by ValidateTokenExchangeRequest
	CreateAccessToken(context.Context, TokenRequest) (accessTokenID string, expiration time.Time, err error)

	// The TokenRequest parameter of CreateAccessAndRefreshTokens can be any of:
	//
	// * TokenRequest as returned by ClientCredentialsStorage.ClientCredentialsTokenRequest
	//
	// * RefreshTokenRequest as returned by AuthStorage.TokenRequestByRefreshToken
	//
	// * AuthRequest as by returned by the AuthRequestByID or AuthRequestByCode (above).
	//   Used for the authorization code flow which requested offline_access scope and
	//   registered the refresh_token grant type in advance
	//
	// * TokenExchangeRequest as returned by ValidateTokenExchangeRequest
	CreateAccessAndRefreshTokens(ctx context.Context, request TokenRequest, currentRefreshToken string) (accessTokenID string, newRefreshTokenID string, expiration time.Time, err error)
	TokenRequestByRefreshToken(ctx context.Context, refreshTokenID string) (RefreshTokenRequest, error)

	TerminateSession(ctx context.Context, userID string, clientID string) error

	// RevokeToken should revoke a token. In the situation that the original request was to
	// revoke an access token, then tokenOrTokenID will be a tokenID and userID will be set
	// but if the original request was for a refresh token, then userID will be empty and
	// tokenOrTokenID will be the refresh token, not its ID.  RevokeToken depends upon GetRefreshTokenInfo
	// to get information from refresh tokens that are not either "<tokenID>:<userID>" strings
	// nor JWTs.
	RevokeToken(ctx context.Context, tokenOrTokenID string, userID string, clientID string) *oidc.Error

	// GetRefreshTokenInfo must return ErrInvalidRefreshToken when presented
	// with a token that is not a refresh token.
	GetRefreshTokenInfo(ctx context.Context, clientID string, token string) (userID string, tokenID string, err error)

	SigningKey(context.Context) (SigningKey, error)
	SignatureAlgorithms(context.Context) ([]jose.SignatureAlgorithm, error)
	KeySet(context.Context) ([]Key, error)
}

type AuthenticatedTokenRequest

type AuthenticatedTokenRequest interface {
	SetClientID(string)
	SetClientSecret(string)
}

AuthenticatedTokenRequest is a helper interface for ParseAuthenticatedTokenRequest it is implemented by oidc.AuthRequest and oidc.RefreshTokenRequest

type AuthorizeValidator

type AuthorizeValidator interface {
	Authorizer
	ValidateAuthRequest(context.Context, *oidc.AuthRequest, Storage, *IDTokenHintVerifier) (string, error)
}

AuthorizeValidator is an extension of Authorizer interface implementing its own validation mechanism for the auth request

type Authorizer

type Authorizer interface {
	Storage() Storage
	Decoder() httphelper.Decoder
	Encoder() httphelper.Encoder
	IDTokenHintVerifier(context.Context) *IDTokenHintVerifier
	Crypto() Crypto
	RequestObjectSupported() bool
	Logger() *slog.Logger
}

type CanSetUserinfoFromRequest

type CanSetUserinfoFromRequest interface {
	SetUserinfoFromRequest(ctx context.Context, userinfo *oidc.UserInfo, request IDTokenRequest, scopes []string) error
}

CanSetUserinfoFromRequest is an optional additional interface that may be implemented by implementors of Storage. It allows additional data to be set in id_tokens based on the request.

type CanTerminateSessionFromRequest

type CanTerminateSessionFromRequest interface {
	TerminateSessionFromRequest(ctx context.Context, endSessionRequest *EndSessionRequest) (string, error)
}

CanTerminateSessionFromRequest is an optional additional interface that may be implemented by implementors of Storage as an alternative to TerminateSession of the AuthStorage. It passes the complete parsed EndSessionRequest to the implementation, which allows access to additional data. It also allows to modify the uri, which will be used for redirection, (e.g. a UI where the user can consent to the logout)

type Client

type Client interface {
	GetID() string
	RedirectURIs() []string
	PostLogoutRedirectURIs() []string
	ApplicationType() ApplicationType
	AuthMethod() oidc.AuthMethod
	ResponseTypes() []oidc.ResponseType
	GrantTypes() []oidc.GrantType
	LoginURL(string) string
	AccessTokenType() AccessTokenType
	IDTokenLifetime() time.Duration
	DevMode() bool
	RestrictAdditionalIdTokenScopes() func(scopes []string) []string
	RestrictAdditionalAccessTokenScopes() func(scopes []string) []string
	IsScopeAllowed(scope string) bool
	IDTokenUserinfoClaimsAssertion() bool
	ClockSkew() time.Duration
}

func AuthorizeClientCredentialsClient

func AuthorizeClientCredentialsClient(ctx context.Context, request *oidc.ClientCredentialsRequest, storage ClientCredentialsStorage) (Client, error)

func AuthorizePrivateJWTKey

func AuthorizePrivateJWTKey(ctx context.Context, clientAssertion string, exchanger JWTAuthorizationGrantExchanger) (Client, error)

AuthorizePrivateJWTKey authorizes a client by validating the client_assertion's signature with a previously registered public key (JWT Profile)

func AuthorizeTokenExchangeClient

func AuthorizeTokenExchangeClient(ctx context.Context, clientID, clientSecret string, exchanger Exchanger) (client Client, err error)

AuthorizeTokenExchangeClient authorizes a client by validating the client_id and client_secret

type ClientCredentials

type ClientCredentials struct {
	ClientID            string `schema:"client_id"`
	ClientSecret        string `schema:"client_secret"`    // Client secret from Basic auth or request body
	ClientAssertion     string `schema:"client_assertion"` // JWT
	ClientAssertionType string `schema:"client_assertion_type"`
}

type ClientCredentialsStorage

type ClientCredentialsStorage interface {
	ClientCredentials(ctx context.Context, clientID, clientSecret string) (Client, error)
	ClientCredentialsTokenRequest(ctx context.Context, clientID string, scopes []string) (TokenRequest, error)
}

type ClientJWTProfile

type ClientJWTProfile interface {
	JWTProfileVerifier(context.Context) *JWTProfileVerifier
}

type ClientProvider

type ClientProvider interface {
	Decoder() httphelper.Decoder
	Storage() Storage
}

type ClientRequest

type ClientRequest[T any] struct {
	*Request[T]
	Client Client
}

ClientRequest is a Request with a verified client attached to it. Methods that receive this argument may assume the client was authenticated, or verified to be a public client.

EXPERIMENTAL: may change until v4

type Config

type Config struct {
	CryptoKey                [32]byte
	DefaultLogoutRedirectURI string
	CodeMethodS256           bool
	AuthMethodPost           bool
	AuthMethodPrivateKeyJWT  bool
	GrantTypeRefreshToken    bool
	RequestObjectSupported   bool
	SupportedUILocales       []language.Tag
	SupportedClaims          []string
	DeviceAuthorization      DeviceAuthorizationConfig
}

type Configuration

type Configuration interface {
	IssuerFromRequest(r *http.Request) string
	Insecure() bool
	AuthorizationEndpoint() *Endpoint
	TokenEndpoint() *Endpoint
	IntrospectionEndpoint() *Endpoint
	UserinfoEndpoint() *Endpoint
	RevocationEndpoint() *Endpoint
	EndSessionEndpoint() *Endpoint
	KeysEndpoint() *Endpoint
	DeviceAuthorizationEndpoint() *Endpoint

	AuthMethodPostSupported() bool
	CodeMethodS256Supported() bool
	AuthMethodPrivateKeyJWTSupported() bool
	TokenEndpointSigningAlgorithmsSupported() []string
	GrantTypeRefreshTokenSupported() bool
	GrantTypeTokenExchangeSupported() bool
	GrantTypeJWTAuthorizationSupported() bool
	GrantTypeClientCredentialsSupported() bool
	GrantTypeDeviceCodeSupported() bool
	IntrospectionAuthMethodPrivateKeyJWTSupported() bool
	IntrospectionEndpointSigningAlgorithmsSupported() []string
	RevocationAuthMethodPrivateKeyJWTSupported() bool
	RevocationEndpointSigningAlgorithmsSupported() []string
	RequestObjectSupported() bool
	RequestObjectSigningAlgorithmsSupported() []string

	SupportedUILocales() []language.Tag
	DeviceAuthorization() DeviceAuthorizationConfig
}

type Crypto

type Crypto interface {
	Encrypt(string) (string, error)
	Decrypt(string) (string, error)
}

func NewAESCrypto

func NewAESCrypto(key [32]byte) Crypto

type DeviceAuthorizationConfig

type DeviceAuthorizationConfig struct {
	Lifetime     time.Duration
	PollInterval time.Duration

	// UserFormURL is the complete URL where the user must go to authorize the device.
	// Deprecated: use UserFormPath instead.
	UserFormURL string

	// UserFormPath is the path where the user must go to authorize the device.
	// The hostname for the URL is taken from the request by IssuerFromContext.
	UserFormPath string
	UserCode     UserCodeConfig
}

type DeviceAuthorizationState

type DeviceAuthorizationState struct {
	ClientID string
	Audience []string
	Scopes   []string
	Expires  time.Time // The time after we consider the authorization request timed-out
	Done     bool      // The user authenticated and approved the authorization request
	Denied   bool      // The user authenticated and denied the authorization request

	// The following fields are populated after Done == true
	Subject  string
	AMR      []string
	AuthTime time.Time
}

DeviceAuthorizationState describes the current state of the device authorization flow. It implements the IDTokenRequest interface.

func CheckDeviceAuthorizationState

func CheckDeviceAuthorizationState(ctx context.Context, clientID, deviceCode string, exchanger Exchanger) (*DeviceAuthorizationState, error)

func (*DeviceAuthorizationState) GetAMR added in v3.8.0

func (r *DeviceAuthorizationState) GetAMR() []string

func (*DeviceAuthorizationState) GetAudience added in v3.8.0

func (r *DeviceAuthorizationState) GetAudience() []string

func (*DeviceAuthorizationState) GetAuthTime added in v3.8.0

func (r *DeviceAuthorizationState) GetAuthTime() time.Time

func (*DeviceAuthorizationState) GetClientID added in v3.8.0

func (r *DeviceAuthorizationState) GetClientID() string

func (*DeviceAuthorizationState) GetScopes added in v3.8.0

func (r *DeviceAuthorizationState) GetScopes() []string

func (*DeviceAuthorizationState) GetSubject added in v3.8.0

func (r *DeviceAuthorizationState) GetSubject() string

type DeviceAuthorizationStorage

type DeviceAuthorizationStorage interface {
	// StoreDeviceAuthorizationRequest stores a new device authorization request in the database.
	// User code will be used by the user to complete the login flow and must be unique.
	// ErrDuplicateUserCode signals the caller should try again with a new code.
	//
	// Note that user codes are low entropy keys and when many exist in the
	// database, the change for collisions increases. Therefore implementers
	// of this interface must make sure that user codes of expired authentication flows are purged,
	// after some time.
	StoreDeviceAuthorization(ctx context.Context, clientID, deviceCode, userCode string, expires time.Time, scopes []string) error

	// GetDeviceAuthorizatonState returns the current state of the device authorization flow in the database.
	// The method is polled untill the the authorization is eighter Completed, Expired or Denied.
	GetDeviceAuthorizatonState(ctx context.Context, clientID, deviceCode string) (*DeviceAuthorizationState, error)
}

type DiscoverStorage

type DiscoverStorage interface {
	SignatureAlgorithms(context.Context) ([]jose.SignatureAlgorithm, error)
}

type EndSessionRequest

type EndSessionRequest struct {
	UserID            string
	ClientID          string
	IDTokenHintClaims *oidc.IDTokenClaims
	RedirectURI       string
}

func ValidateEndSessionRequest

func ValidateEndSessionRequest(ctx context.Context, req *oidc.EndSessionRequest, ender SessionEnder) (*EndSessionRequest, error)

type Endpoint

type Endpoint struct {
	// contains filtered or unexported fields
}

func NewEndpoint

func NewEndpoint(path string) *Endpoint

func NewEndpointWithURL

func NewEndpointWithURL(path, url string) *Endpoint

func (*Endpoint) Absolute

func (e *Endpoint) Absolute(host string) string

func (*Endpoint) Relative

func (e *Endpoint) Relative() string

func (*Endpoint) Validate

func (e *Endpoint) Validate() error

type Endpoints

type Endpoints struct {
	Authorization       *Endpoint
	Token               *Endpoint
	Introspection       *Endpoint
	Userinfo            *Endpoint
	Revocation          *Endpoint
	EndSession          *Endpoint
	CheckSessionIframe  *Endpoint
	JwksURI             *Endpoint
	DeviceAuthorization *Endpoint
}

Endpoints defines endpoint routes.

type ErrAuthRequest

type ErrAuthRequest interface {
	GetRedirectURI() string
	GetResponseType() oidc.ResponseType
	GetState() string
}

type Exchanger

type Exchanger interface {
	Storage() Storage
	Decoder() httphelper.Decoder
	Crypto() Crypto
	AuthMethodPostSupported() bool
	AuthMethodPrivateKeyJWTSupported() bool
	GrantTypeRefreshTokenSupported() bool
	GrantTypeTokenExchangeSupported() bool
	GrantTypeJWTAuthorizationSupported() bool
	GrantTypeClientCredentialsSupported() bool
	GrantTypeDeviceCodeSupported() bool
	AccessTokenVerifier(context.Context) *AccessTokenVerifier
	IDTokenHintVerifier(context.Context) *IDTokenHintVerifier
	Logger() *slog.Logger
}

type ExtendedLegacyServer added in v3.1.0

type ExtendedLegacyServer interface {
	Server
	Provider() OpenIDProvider
	Endpoints() Endpoints
	AuthCallbackURL() func(context.Context, string) string
}

ExtendedLegacyServer allows embedding LegacyServer in a struct, so that its methods can be individually overridden.

EXPERIMENTAL: may change until v4

type HasRedirectGlobs

type HasRedirectGlobs interface {
	Client
	RedirectURIGlobs() []string
	PostLogoutRedirectURIGlobs() []string
}

HasRedirectGlobs is an optional interface that can be implemented by implementors of Client. See https://pkg.go.dev/path#Match for glob interpretation. Redirect URIs that match either the non-glob version or the glob version will be accepted. Glob URIs are only partially supported for native clients: "http://" is not allowed except for loopback or in dev mode.

Note that globbing / wildcards are not permitted by the OIDC standard and implementing this interface can have security implications. It is advised to only return a client of this type in rare cases, such as DevMode for the client being enabled. https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

type HttpInterceptor

type HttpInterceptor func(http.Handler) http.Handler

type IDTokenHintExpiredError added in v3.10.3

type IDTokenHintExpiredError struct {
	// contains filtered or unexported fields
}

func (IDTokenHintExpiredError) Is added in v3.10.3

func (IDTokenHintExpiredError) Unwrap added in v3.10.3

func (e IDTokenHintExpiredError) Unwrap() error

type IDTokenHintVerifier

type IDTokenHintVerifier oidc.Verifier

func NewIDTokenHintVerifier

func NewIDTokenHintVerifier(issuer string, keySet oidc.KeySet, opts ...IDTokenHintVerifierOpt) *IDTokenHintVerifier

type IDTokenHintVerifierOpt

type IDTokenHintVerifierOpt func(*IDTokenHintVerifier)

func WithSupportedIDTokenHintSigningAlgorithms

func WithSupportedIDTokenHintSigningAlgorithms(algs ...string) IDTokenHintVerifierOpt

type IDTokenRequest

type IDTokenRequest interface {
	GetAMR() []string
	GetAudience() []string
	GetAuthTime() time.Time
	GetClientID() string
	GetScopes() []string
	GetSubject() string
}

type IntrospectionRequest added in v3.1.1

type IntrospectionRequest struct {
	*ClientCredentials
	*oidc.IntrospectionRequest
}

type Introspector

type Introspector interface {
	Decoder() httphelper.Decoder
	Crypto() Crypto
	Storage() Storage
	AccessTokenVerifier(context.Context) *AccessTokenVerifier
}

type IntrospectorJWTProfile

type IntrospectorJWTProfile interface {
	Introspector
	JWTProfileVerifier(context.Context) JWTProfileVerifier
}

type IssuerFromOption added in v3.2.0

type IssuerFromOption func(c *issuerConfig)

func WithIssuerFromCustomHeaders added in v3.2.0

func WithIssuerFromCustomHeaders(headers ...string) IssuerFromOption

WithIssuerFromCustomHeaders can be used to customize the header names used. The same rules apply where the first successful host is returned.

type IssuerFromRequest

type IssuerFromRequest func(r *http.Request) string

type IssuerInterceptor

type IssuerInterceptor struct {
	// contains filtered or unexported fields
}

func NewIssuerInterceptor

func NewIssuerInterceptor(issuerFromRequest IssuerFromRequest) *IssuerInterceptor

NewIssuerInterceptor will set the issuer into the context by the provided IssuerFromRequest (e.g. returned from StaticIssuer or IssuerFromHost)

func (*IssuerInterceptor) Handler

func (i *IssuerInterceptor) Handler(next http.Handler) http.Handler

func (*IssuerInterceptor) HandlerFunc

func (i *IssuerInterceptor) HandlerFunc(next http.HandlerFunc) http.HandlerFunc

type JWTAuthorizationGrantExchanger

type JWTAuthorizationGrantExchanger interface {
	Exchanger
	JWTProfileVerifier(context.Context) *JWTProfileVerifier
}

type JWTProfileKeyStorage

type JWTProfileKeyStorage interface {
	GetKeyByIDAndClientID(ctx context.Context, keyID, userID string) (*jose.JSONWebKey, error)
}

type JWTProfileTokenStorage

type JWTProfileTokenStorage interface {
	JWTProfileTokenType(ctx context.Context, request TokenRequest) (AccessTokenType, error)
}

JWTProfileTokenStorage is an additional, optional storage to implement implementing it, allows specifying the AccessTokenType of the access_token returned form the JWT Profile TokenRequest

type JWTProfileVerifier

type JWTProfileVerifier struct {
	oidc.Verifier
	Storage JWTProfileKeyStorage

	CheckSubject func(request *oidc.JWTTokenRequest) error
	// contains filtered or unexported fields
}

JWTProfileVerfiier extends oidc.Verifier with a jwtProfileKeyStorage and a function to check the subject in a token.

func NewJWTProfileVerifier

func NewJWTProfileVerifier(storage JWTProfileKeyStorage, issuer string, maxAgeIAT, offset time.Duration, opts ...JWTProfileVerifierOption) *JWTProfileVerifier

NewJWTProfileVerifier creates a oidc.Verifier for JWT Profile assertions (authorization grant and client authentication)

func NewJWTProfileVerifierKeySet added in v3.4.0

func NewJWTProfileVerifierKeySet(keySet oidc.KeySet, issuer string, maxAgeIAT, offset time.Duration, opts ...JWTProfileVerifierOption) *JWTProfileVerifier

NewJWTProfileVerifierKeySet creates a oidc.Verifier for JWT Profile assertions (authorization grant and client authentication)

type JWTProfileVerifierOption

type JWTProfileVerifierOption func(*JWTProfileVerifier)

func SubjectCheck

func SubjectCheck(check func(request *oidc.JWTTokenRequest) error) JWTProfileVerifierOption

SubjectCheck sets a custom function to check the subject. Defaults to SubjectIsIssuer()

type Key

type Key interface {
	ID() string
	Algorithm() jose.SignatureAlgorithm
	Use() string
	Key() any
}

type KeyProvider

type KeyProvider interface {
	KeySet(context.Context) ([]Key, error)
}

type LegacyServer

type LegacyServer struct {
	UnimplementedServer
	// contains filtered or unexported fields
}

LegacyServer is an implementation of Server that simply wraps an OpenIDProvider. It can be used to transition from the former Provider/Storage interfaces to the new Server interface.

EXPERIMENTAL: may change until v4

func NewLegacyServer

func NewLegacyServer(provider OpenIDProvider, endpoints Endpoints) *LegacyServer

NewLegacyServer wraps provider in a `Server` implementation

Only non-nil endpoints will be registered on the router. Nil endpoints are disabled.

The passed endpoints is also used for the discovery config, and endpoints already set to the provider are ignored. Any `With*Endpoint()` option used on the provider is therefore ineffective.

EXPERIMENTAL: may change until v4

func (*LegacyServer) AuthCallbackURL added in v3.1.1

func (s *LegacyServer) AuthCallbackURL() func(context.Context, string) string

AuthCallbackURL builds the url for the redirect (with the requestID) after a successful login

func (*LegacyServer) Authorize

func (s *LegacyServer) Authorize(ctx context.Context, r *ClientRequest[oidc.AuthRequest]) (_ *Redirect, err error)

func (*LegacyServer) ClientCredentialsExchange

func (s *LegacyServer) ClientCredentialsExchange(ctx context.Context, r *ClientRequest[oidc.ClientCredentialsRequest]) (*Response, error)

func (*LegacyServer) CodeExchange

func (*LegacyServer) DeviceAuthorization

func (*LegacyServer) DeviceToken

func (*LegacyServer) Discovery

func (s *LegacyServer) Discovery(ctx context.Context, r *Request[struct{}]) (*Response, error)

func (*LegacyServer) EndSession

func (*LegacyServer) Endpoints added in v3.1.0

func (s *LegacyServer) Endpoints() Endpoints

func (*LegacyServer) Health

func (s *LegacyServer) Health(_ context.Context, r *Request[struct{}]) (*Response, error)

func (*LegacyServer) Introspect

func (*LegacyServer) JWTProfile

func (*LegacyServer) Keys

func (s *LegacyServer) Keys(ctx context.Context, r *Request[struct{}]) (*Response, error)

func (*LegacyServer) Provider added in v3.1.0

func (s *LegacyServer) Provider() OpenIDProvider

func (*LegacyServer) Ready

func (s *LegacyServer) Ready(ctx context.Context, r *Request[struct{}]) (*Response, error)

func (*LegacyServer) RefreshToken

func (*LegacyServer) Revocation

func (*LegacyServer) TokenExchange

func (*LegacyServer) UserInfo

func (*LegacyServer) VerifyAuthRequest

func (s *LegacyServer) VerifyAuthRequest(ctx context.Context, r *Request[oidc.AuthRequest]) (*ClientRequest[oidc.AuthRequest], error)

func (*LegacyServer) VerifyClient

func (s *LegacyServer) VerifyClient(ctx context.Context, r *Request[ClientCredentials]) (Client, error)

type LogAuthRequest

type LogAuthRequest interface {
	ErrAuthRequest
	slog.LogValuer
}

LogAuthRequest is an optional interface, that allows logging AuthRequest fields. If the AuthRequest does not implement this interface, no details shall be printed to the logs.

type OPStorage

type OPStorage interface {
	// GetClientByClientID loads a Client. The returned Client is never cached and is only used to
	// handle the current request.
	GetClientByClientID(ctx context.Context, clientID string) (Client, error)
	AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string) error
	// SetUserinfoFromScopes is deprecated and should have an empty implementation for now.
	// Implement SetUserinfoFromRequest instead.
	SetUserinfoFromScopes(ctx context.Context, userinfo *oidc.UserInfo, userID, clientID string, scopes []string) error
	SetUserinfoFromToken(ctx context.Context, userinfo *oidc.UserInfo, tokenID, subject, origin string) error
	SetIntrospectionFromToken(ctx context.Context, userinfo *oidc.IntrospectionResponse, tokenID, subject, clientID string) error
	GetPrivateClaimsFromScopes(ctx context.Context, userID, clientID string, scopes []string) (map[string]any, error)
	GetKeyByIDAndClientID(ctx context.Context, keyID, clientID string) (*jose.JSONWebKey, error)
	ValidateJWTProfileScopes(ctx context.Context, userID string, scopes []string) ([]string, error)
}

type OpenIDKeySet added in v3.11.0

type OpenIDKeySet struct {
	Storage
}

func (*OpenIDKeySet) VerifySignature added in v3.11.0

func (o *OpenIDKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error)

VerifySignature implements the oidc.KeySet interface providing an implementation for the keys stored in the OP Storage interface

type OpenIDProvider

type OpenIDProvider interface {
	http.Handler
	Configuration
	Storage() Storage
	Decoder() httphelper.Decoder
	Encoder() httphelper.Encoder
	IDTokenHintVerifier(context.Context) *IDTokenHintVerifier
	AccessTokenVerifier(context.Context) *AccessTokenVerifier
	Crypto() Crypto
	DefaultLogoutRedirectURI() string
	Probes() []ProbesFn
	Logger() *slog.Logger

	// Deprecated: Provider now implements http.Handler directly.
	HttpHandler() http.Handler
}

type Option

type Option func(o *Provider) error

func WithAccessTokenKeySet added in v3.11.0

func WithAccessTokenKeySet(keySet oidc.KeySet) Option

WithAccessTokenKeySet allows passing a KeySet with public keys for Access Token verification. The default KeySet uses the Storage interface

func WithAccessTokenVerifierOpts

func WithAccessTokenVerifierOpts(opts ...AccessTokenVerifierOpt) Option

func WithAllowInsecure

func WithAllowInsecure() Option

WithAllowInsecure allows the use of http (instead of https) for issuers this is not recommended for production use and violates the OIDC specification

func WithCORSOptions added in v3.3.0

func WithCORSOptions(opts *cors.Options) Option

func WithCustomAuthEndpoint

func WithCustomAuthEndpoint(endpoint *Endpoint) Option

func WithCustomDeviceAuthorizationEndpoint

func WithCustomDeviceAuthorizationEndpoint(endpoint *Endpoint) Option

func WithCustomEndSessionEndpoint

func WithCustomEndSessionEndpoint(endpoint *Endpoint) Option

func WithCustomEndpoints

func WithCustomEndpoints(auth, token, userInfo, revocation, endSession, keys *Endpoint) Option

WithCustomEndpoints sets multiple endpoints at once. Non of the endpoints may be nil, or an error will be returned when the Option used by the Provider.

func WithCustomIntrospectionEndpoint

func WithCustomIntrospectionEndpoint(endpoint *Endpoint) Option

func WithCustomKeysEndpoint

func WithCustomKeysEndpoint(endpoint *Endpoint) Option

func WithCustomRevocationEndpoint

func WithCustomRevocationEndpoint(endpoint *Endpoint) Option

func WithCustomTokenEndpoint

func WithCustomTokenEndpoint(endpoint *Endpoint) Option

func WithCustomUserinfoEndpoint

func WithCustomUserinfoEndpoint(endpoint *Endpoint) Option

func WithHttpInterceptors

func WithHttpInterceptors(interceptors ...HttpInterceptor) Option

func WithIDTokenHintKeySet added in v3.11.0

func WithIDTokenHintKeySet(keySet oidc.KeySet) Option

WithIDTokenHintKeySet allows passing a KeySet with public keys for ID Token Hint verification. The default KeySet uses the Storage interface.

func WithIDTokenHintVerifierOpts

func WithIDTokenHintVerifierOpts(opts ...IDTokenHintVerifierOpt) Option

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger lets a logger other than slog.Default().

type ProbesFn

type ProbesFn func(context.Context) error

func ReadyStorage

func ReadyStorage(s Storage) ProbesFn

type Provider

type Provider struct {
	http.Handler
	// contains filtered or unexported fields
}

func NewDynamicOpenIDProvider deprecated

func NewDynamicOpenIDProvider(path string, config *Config, storage Storage, opOpts ...Option) (*Provider, error)

NewForwardedOpenIDProvider tries to establishes the issuer from the request Host.

Deprecated: use NewProvider with an issuer function direct.

func NewForwardedOpenIDProvider deprecated

func NewForwardedOpenIDProvider(path string, config *Config, storage Storage, opOpts ...Option) (*Provider, error)

NewForwardedOpenIDProvider tries to establish the Issuer from a Forwarded request header, if it is set. See IssuerFromForwardedOrHost for details.

Deprecated: use NewProvider with an issuer function direct.

func NewOpenIDProvider deprecated

func NewOpenIDProvider(issuer string, config *Config, storage Storage, opOpts ...Option) (*Provider, error)

NewOpenIDProvider creates a provider. The provider provides (with HttpHandler()) a http.Router that handles a suite of endpoints (some paths can be overridden):

/healthz
/ready
/.well-known/openid-configuration
/oauth/token
/oauth/introspect
/callback
/authorize
/userinfo
/revoke
/end_session
/keys
/device_authorization

This does not include login. Login is handled with a redirect that includes the request ID. The redirect for logins is specified per-client by Client.LoginURL(). Successful logins should mark the request as authorized and redirect back to to op.AuthCallbackURL(provider) which is probably /callback. On the redirect back to the AuthCallbackURL, the request id should be passed as the "id" parameter.

Deprecated: use NewProvider with an issuer function direct.

func NewProvider added in v3.2.1

func NewProvider(config *Config, storage Storage, issuer func(insecure bool) (IssuerFromRequest, error), opOpts ...Option) (_ *Provider, err error)

NewProvider creates a provider with a router on it's embedded http.Handler. Issuer is a function that must return the issuer on every request. Typically StaticIssuer, IssuerFromHost or IssuerFromForwardedOrHost can be used.

The router handles a suite of endpoints (some paths can be overridden):

/healthz
/ready
/.well-known/openid-configuration
/oauth/token
/oauth/introspect
/callback
/authorize
/userinfo
/revoke
/end_session
/keys
/device_authorization

This does not include login. Login is handled with a redirect that includes the request ID. The redirect for logins is specified per-client by Client.LoginURL(). Successful logins should mark the request as authorized and redirect back to to op.AuthCallbackURL(provider) which is probably /callback. On the redirect back to the AuthCallbackURL, the request id should be passed as the "id" parameter.

func (*Provider) AccessTokenVerifier

func (o *Provider) AccessTokenVerifier(ctx context.Context) *AccessTokenVerifier

func (*Provider) AuthMethodPostSupported

func (o *Provider) AuthMethodPostSupported() bool

func (*Provider) AuthMethodPrivateKeyJWTSupported

func (o *Provider) AuthMethodPrivateKeyJWTSupported() bool

func (*Provider) AuthorizationEndpoint

func (o *Provider) AuthorizationEndpoint() *Endpoint

func (*Provider) CORSOptions added in v3.3.0

func (o *Provider) CORSOptions() *cors.Options

func (*Provider) CodeMethodS256Supported

func (o *Provider) CodeMethodS256Supported() bool

func (*Provider) Crypto

func (o *Provider) Crypto() Crypto

func (*Provider) Decoder

func (o *Provider) Decoder() httphelper.Decoder

func (*Provider) DefaultLogoutRedirectURI

func (o *Provider) DefaultLogoutRedirectURI() string

func (*Provider) DeviceAuthorization

func (o *Provider) DeviceAuthorization() DeviceAuthorizationConfig

func (*Provider) DeviceAuthorizationEndpoint

func (o *Provider) DeviceAuthorizationEndpoint() *Endpoint

func (*Provider) Encoder

func (o *Provider) Encoder() httphelper.Encoder

func (*Provider) EndSessionEndpoint

func (o *Provider) EndSessionEndpoint() *Endpoint

func (*Provider) GrantTypeClientCredentialsSupported

func (o *Provider) GrantTypeClientCredentialsSupported() bool

func (*Provider) GrantTypeDeviceCodeSupported

func (o *Provider) GrantTypeDeviceCodeSupported() bool

func (*Provider) GrantTypeJWTAuthorizationSupported

func (o *Provider) GrantTypeJWTAuthorizationSupported() bool

func (*Provider) GrantTypeRefreshTokenSupported

func (o *Provider) GrantTypeRefreshTokenSupported() bool

func (*Provider) GrantTypeTokenExchangeSupported

func (o *Provider) GrantTypeTokenExchangeSupported() bool

func (*Provider) HttpHandler deprecated

func (o *Provider) HttpHandler() http.Handler

Deprecated: Provider now implements http.Handler directly.

func (*Provider) IDTokenHintVerifier

func (o *Provider) IDTokenHintVerifier(ctx context.Context) *IDTokenHintVerifier

func (*Provider) Insecure

func (o *Provider) Insecure() bool

func (*Provider) IntrospectionAuthMethodPrivateKeyJWTSupported

func (o *Provider) IntrospectionAuthMethodPrivateKeyJWTSupported() bool

func (*Provider) IntrospectionEndpoint

func (o *Provider) IntrospectionEndpoint() *Endpoint

func (*Provider) IntrospectionEndpointSigningAlgorithmsSupported

func (o *Provider) IntrospectionEndpointSigningAlgorithmsSupported() []string

func (*Provider) IssuerFromRequest

func (o *Provider) IssuerFromRequest(r *http.Request) string

func (*Provider) JWTProfileVerifier

func (o *Provider) JWTProfileVerifier(ctx context.Context) *JWTProfileVerifier

func (*Provider) KeysEndpoint

func (o *Provider) KeysEndpoint() *Endpoint

func (*Provider) Logger

func (o *Provider) Logger() *slog.Logger

func (*Provider) Probes

func (o *Provider) Probes() []ProbesFn

func (*Provider) RequestObjectSigningAlgorithmsSupported

func (o *Provider) RequestObjectSigningAlgorithmsSupported() []string

func (*Provider) RequestObjectSupported

func (o *Provider) RequestObjectSupported() bool

func (*Provider) RevocationAuthMethodPrivateKeyJWTSupported

func (o *Provider) RevocationAuthMethodPrivateKeyJWTSupported() bool

func (*Provider) RevocationEndpoint

func (o *Provider) RevocationEndpoint() *Endpoint

func (*Provider) RevocationEndpointSigningAlgorithmsSupported

func (o *Provider) RevocationEndpointSigningAlgorithmsSupported() []string

func (*Provider) Storage

func (o *Provider) Storage() Storage

func (*Provider) SupportedUILocales

func (o *Provider) SupportedUILocales() []language.Tag

func (*Provider) TokenEndpoint

func (o *Provider) TokenEndpoint() *Endpoint

func (*Provider) TokenEndpointSigningAlgorithmsSupported

func (o *Provider) TokenEndpointSigningAlgorithmsSupported() []string

func (*Provider) UserinfoEndpoint

func (o *Provider) UserinfoEndpoint() *Endpoint

type Redirect

type Redirect struct {
	// Header map will be merged with the
	// header on the [http.ResponseWriter].
	Header http.Header

	URL string
}

Redirect is a special response type which will initiate a http.StatusFound redirect. The Params field will be encoded and set to the URL's RawQuery field before building the URL.

EXPERIMENTAL: may change until v4

func NewRedirect

func NewRedirect(url string) *Redirect

func TryErrorRedirect

func TryErrorRedirect(ctx context.Context, authReq ErrAuthRequest, parent error, encoder httphelper.Encoder, logger *slog.Logger) (*Redirect, error)

TryErrorRedirect tries to handle an error by redirecting a client. If this attempt fails, an error is returned that must be returned to the client instead.

type RefreshTokenRequest

type RefreshTokenRequest interface {
	GetAMR() []string
	GetAudience() []string
	GetAuthTime() time.Time
	GetClientID() string
	GetScopes() []string
	GetSubject() string
	SetCurrentScopes(scopes []string)
}

func RefreshTokenRequestByRefreshToken

func RefreshTokenRequestByRefreshToken(ctx context.Context, storage Storage, refreshToken string) (RefreshTokenRequest, error)

RefreshTokenRequestByRefreshToken returns the RefreshTokenRequest (data representing the original auth request) corresponding to the refresh_token from Storage or an error

type Request

type Request[T any] struct {
	Method   string
	URL      *url.URL
	Header   http.Header
	Form     url.Values
	PostForm url.Values
	Data     *T
}

Request contains the http.Request informational fields and parsed Data from the request body (POST) or URL parameters (GET). Data can be assumed to be validated according to the applicable standard for the specific endpoints.

EXPERIMENTAL: may change until v4

type Response

type Response struct {
	// Header map will be merged with the
	// header on the [http.ResponseWriter].
	Header http.Header

	// Data will be JSON marshaled to
	// the response body.
	// We allow any type, so that implementations
	// can extend the standard types as they wish.
	// However, each method will recommend which
	// (base) type to use as model, in order to
	// be compliant with the standards.
	Data any
}

Response object for most Server methods.

EXPERIMENTAL: may change until v4

func NewResponse

func NewResponse(data any) *Response

NewResponse creates a new response for data, without custom headers.

type Revoker

type Revoker interface {
	Decoder() httphelper.Decoder
	Crypto() Crypto
	Storage() Storage
	AccessTokenVerifier(context.Context) *AccessTokenVerifier
	AuthMethodPrivateKeyJWTSupported() bool
	AuthMethodPostSupported() bool
}

type RevokerJWTProfile

type RevokerJWTProfile interface {
	Revoker
	JWTProfileVerifier(context.Context) *JWTProfileVerifier
}

type Server

type Server interface {
	// Health returns a status of "ok" once the Server is listening.
	// The recommended Response Data type is [Status].
	Health(context.Context, *Request[struct{}]) (*Response, error)

	// Ready returns a status of "ok" once all dependencies,
	// such as database storage, are ready.
	// An error can be returned to explain what is not ready.
	// The recommended Response Data type is [Status].
	Ready(context.Context, *Request[struct{}]) (*Response, error)

	// Discovery returns the OpenID Provider Configuration Information for this server.
	// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
	// The recommended Response Data type is [oidc.DiscoveryConfiguration].
	Discovery(context.Context, *Request[struct{}]) (*Response, error)

	// Keys serves the JWK set which the client can use verify signatures from the op.
	// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata `jwks_uri` key.
	// The recommended Response Data type is [jose.JSONWebKeySet].
	Keys(context.Context, *Request[struct{}]) (*Response, error)

	// VerifyAuthRequest verifies the Auth Request and
	// adds the Client to the request.
	//
	// When the `request` field is populated with a
	// "Request Object" JWT, it needs to be Validated
	// and its claims overwrite any fields in the AuthRequest.
	// If the implementation does not support "Request Object",
	// it MUST return an [oidc.ErrRequestNotSupported].
	// https://openid.net/specs/openid-connect-core-1_0.html#RequestObject
	VerifyAuthRequest(context.Context, *Request[oidc.AuthRequest]) (*ClientRequest[oidc.AuthRequest], error)

	// Authorize initiates the authorization flow and redirects to a login page.
	// See the various https://openid.net/specs/openid-connect-core-1_0.html
	// authorize endpoint sections (one for each type of flow).
	Authorize(context.Context, *ClientRequest[oidc.AuthRequest]) (*Redirect, error)

	// DeviceAuthorization initiates the device authorization flow.
	// https://datatracker.ietf.org/doc/html/rfc8628#section-3.1
	// The recommended Response Data type is [oidc.DeviceAuthorizationResponse].
	DeviceAuthorization(context.Context, *ClientRequest[oidc.DeviceAuthorizationRequest]) (*Response, error)

	// VerifyClient is called on most oauth/token handlers to authenticate,
	// using either a secret (POST, Basic) or assertion (JWT).
	// If no secrets are provided, the client must be public.
	// This method is called before each method that takes a
	// [ClientRequest] argument.
	VerifyClient(context.Context, *Request[ClientCredentials]) (Client, error)

	// CodeExchange returns Tokens after an authorization code
	// is obtained in a successful Authorize flow.
	// It is called by the Token endpoint handler when
	// grant_type has the value authorization_code
	// https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
	// The recommended Response Data type is [oidc.AccessTokenResponse].
	CodeExchange(context.Context, *ClientRequest[oidc.AccessTokenRequest]) (*Response, error)

	// RefreshToken returns new Tokens after verifying a Refresh token.
	// It is called by the Token endpoint handler when
	// grant_type has the value refresh_token
	// https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens
	// The recommended Response Data type is [oidc.AccessTokenResponse].
	RefreshToken(context.Context, *ClientRequest[oidc.RefreshTokenRequest]) (*Response, error)

	// JWTProfile handles the OAuth 2.0 JWT Profile Authorization Grant
	// It is called by the Token endpoint handler when
	// grant_type has the value urn:ietf:params:oauth:grant-type:jwt-bearer
	// https://datatracker.ietf.org/doc/html/rfc7523#section-2.1
	// The recommended Response Data type is [oidc.AccessTokenResponse].
	JWTProfile(context.Context, *Request[oidc.JWTProfileGrantRequest]) (*Response, error)

	// TokenExchange handles the OAuth 2.0 token exchange grant
	// It is called by the Token endpoint handler when
	// grant_type has the value urn:ietf:params:oauth:grant-type:token-exchange
	// https://datatracker.ietf.org/doc/html/rfc8693
	// The recommended Response Data type is [oidc.AccessTokenResponse].
	TokenExchange(context.Context, *ClientRequest[oidc.TokenExchangeRequest]) (*Response, error)

	// ClientCredentialsExchange handles the OAuth 2.0 client credentials grant
	// It is called by the Token endpoint handler when
	// grant_type has the value client_credentials
	// https://datatracker.ietf.org/doc/html/rfc6749#section-4.4
	// The recommended Response Data type is [oidc.AccessTokenResponse].
	ClientCredentialsExchange(context.Context, *ClientRequest[oidc.ClientCredentialsRequest]) (*Response, error)

	// DeviceToken handles the OAuth 2.0 Device Authorization Grant
	// It is called by the Token endpoint handler when
	// grant_type has the value urn:ietf:params:oauth:grant-type:device_code.
	// It is typically called in a polling fashion and appropriate errors
	// should be returned to signal authorization_pending or access_denied etc.
	// https://datatracker.ietf.org/doc/html/rfc8628#section-3.4,
	// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5.
	// The recommended Response Data type is [oidc.AccessTokenResponse].
	DeviceToken(context.Context, *ClientRequest[oidc.DeviceAccessTokenRequest]) (*Response, error)

	// Introspect handles the OAuth 2.0 Token Introspection endpoint.
	// https://datatracker.ietf.org/doc/html/rfc7662
	// The recommended Response Data type is [oidc.IntrospectionResponse].
	Introspect(context.Context, *Request[IntrospectionRequest]) (*Response, error)

	// UserInfo handles the UserInfo endpoint and returns Claims about the authenticated End-User.
	// https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
	// The recommended Response Data type is [oidc.UserInfo].
	UserInfo(context.Context, *Request[oidc.UserInfoRequest]) (*Response, error)

	// Revocation handles token revocation using an access or refresh token.
	// https://datatracker.ietf.org/doc/html/rfc7009
	// There are no response requirements. Data may remain empty.
	Revocation(context.Context, *ClientRequest[oidc.RevocationRequest]) (*Response, error)

	// EndSession handles the OpenID Connect RP-Initiated Logout.
	// https://openid.net/specs/openid-connect-rpinitiated-1_0.html
	// There are no response requirements. Data may remain empty.
	EndSession(context.Context, *Request[oidc.EndSessionRequest]) (*Redirect, error)
	// contains filtered or unexported methods
}

Server describes the interface that needs to be implemented to serve OpenID Connect and Oauth2 standard requests.

Methods are called after the HTTP route is resolved and the request body is parsed into the Request's Data field. When a method is called, it can be assumed that required fields, as described in their relevant standard, are validated already. The Response Data field may be of any type to allow flexibility to extend responses with custom fields. There are however requirements in the standards regarding the response models. Where applicable the method documentation gives a recommended type which can be used directly or extended upon.

The addition of new methods is not considered a breaking change as defined by semver rules. Implementations MUST embed UnimplementedServer to maintain forward compatibility.

EXPERIMENTAL: may change until v4

type ServerOption

type ServerOption func(s *webServer)

func WithDecoder

func WithDecoder(decoder httphelper.Decoder) ServerOption

WithDecoder overrides the default decoder, which is a schema.Decoder with IgnoreUnknownKeys set to true.

func WithFallbackLogger

func WithFallbackLogger(logger *slog.Logger) ServerOption

WithFallbackLogger overrides the fallback logger, which is used when no logger was found in the context. Defaults to slog.Default.

func WithHTTPMiddleware

func WithHTTPMiddleware(m ...func(http.Handler) http.Handler) ServerOption

WithHTTPMiddleware sets the passed middleware chain to the root of the Server's router.

func WithServerCORSOptions added in v3.3.0

func WithServerCORSOptions(opts *cors.Options) ServerOption

WithServerCORSOptions sets the CORS policy for the Server's router.

func WithSetRouter added in v3.1.0

func WithSetRouter(set func(chi.Router)) ServerOption

WithSetRouter allows customization or the Server's router.

type SessionEnder

type SessionEnder interface {
	Decoder() httphelper.Decoder
	Storage() Storage
	IDTokenHintVerifier(context.Context) *IDTokenHintVerifier
	DefaultLogoutRedirectURI() string
	Logger() *slog.Logger
}

type SigningKey

type SigningKey interface {
	SignatureAlgorithm() jose.SignatureAlgorithm
	Key() any
	ID() string
}

type Status

type Status struct {
	Status string `json:"status,omitempty"`
}

type StatusError

type StatusError struct {
	// contains filtered or unexported fields
}

StatusError wraps an error with a HTTP status code. The status code is passed to the handler's writer.

func AsStatusError

func AsStatusError(err error, statusCode int) (target StatusError)

AsStatusError unwraps a StatusError from err and returns it unmodified if found. If no StatuError was found, a new one is returned with statusCode set to it as a default.

func NewStatusError

func NewStatusError(parent error, statusCode int) StatusError

NewStatusError sets the parent and statusCode to a new StatusError. It is recommended for parent to be an oidc.Error.

Typically implementations should only use this to signal something very specific, like an internal server error. If a returned error is not a StatusError, the framework will set a statusCode based on what the standard specifies, which is http.StatusBadRequest for most of the time. If the error encountered can described clearly with a oidc.Error, do not use this function, as it might break standard rules!

func RevocationError

func RevocationError(err error) StatusError

func (StatusError) Error

func (e StatusError) Error() string

func (StatusError) Is

func (e StatusError) Is(err error) bool

func (StatusError) Unwrap

func (e StatusError) Unwrap() error

type Storage

type Storage interface {
	AuthStorage
	OPStorage
	Health(context.Context) error
}

Storage is a required parameter for NewOpenIDProvider(). In addition to the embedded interfaces below, if the passed Storage implements ClientCredentialsStorage then the grant type "client_credentials" will be supported. In that case, the access token returned by CreateAccessToken should be a JWT. See https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.4 for context.

type StorageNotFoundError

type StorageNotFoundError interface {
	IsNotFound()
}

type TokenActorRequest added in v3.17.0

type TokenActorRequest interface {
	GetActor() *oidc.ActorClaims
}

type TokenCreator

type TokenCreator interface {
	Storage() Storage
	Crypto() Crypto
}

type TokenExchangeRequest

type TokenExchangeRequest interface {
	GetAMR() []string
	GetAudience() []string
	GetResourses() []string
	GetAuthTime() time.Time
	GetClientID() string
	GetScopes() []string
	GetSubject() string
	GetRequestedTokenType() oidc.TokenType

	GetExchangeSubject() string
	GetExchangeSubjectTokenType() oidc.TokenType
	GetExchangeSubjectTokenIDOrToken() string
	GetExchangeSubjectTokenClaims() map[string]any

	GetExchangeActor() string
	GetExchangeActorTokenType() oidc.TokenType
	GetExchangeActorTokenIDOrToken() string
	GetExchangeActorTokenClaims() map[string]any

	SetCurrentScopes(scopes []string)
	SetRequestedTokenType(tt oidc.TokenType)
	SetSubject(subject string)
}

func CreateTokenExchangeRequest

func CreateTokenExchangeRequest(
	ctx context.Context,
	oidcTokenExchangeRequest *oidc.TokenExchangeRequest,
	client Client,
	exchanger Exchanger,
) (TokenExchangeRequest, error)

type TokenExchangeStorage

type TokenExchangeStorage interface {
	// ValidateTokenExchangeRequest will be called to validate parsed (including tokens) Token Exchange Grant request.
	//
	// Important validations can include:
	// - permissions
	// - set requested token type to some default value if it is empty (rfc 8693 allows it) using SetRequestedTokenType method.
	//   Depending on RequestedTokenType - the following tokens will be issued:
	//   - RefreshTokenType - both access and refresh tokens
	//   - AccessTokenType - only access token
	//   - IDTokenType - only id token
	// - validation of subject's token type on possibility to be exchanged to the requested token type (according to your requirements)
	// - scopes (and update them using SetCurrentScopes method)
	// - set new subject if it differs from exchange subject (impersonation flow)
	//
	// Request will include subject's and/or actor's token claims if correspinding tokens are access/id_token issued by op
	// or third party tokens parsed by TokenExchangeTokensVerifierStorage interface methods.
	ValidateTokenExchangeRequest(ctx context.Context, request TokenExchangeRequest) error

	// CreateTokenExchangeRequest will be called after parsing and validating token exchange request.
	// Stored request is not accessed later by op - so it is up to implementer to decide
	// should this method actually store the request or not (common use case - store for it for audit purposes)
	CreateTokenExchangeRequest(ctx context.Context, request TokenExchangeRequest) error

	// GetPrivateClaimsFromTokenExchangeRequest will be called during access token creation.
	// Claims evaluation can be based on all validated request data available, including: scopes, resource, audience, etc.
	GetPrivateClaimsFromTokenExchangeRequest(ctx context.Context, request TokenExchangeRequest) (claims map[string]any, err error)

	// SetUserinfoFromTokenExchangeRequest will be called during id token creation.
	// Claims evaluation can be based on all validated request data available, including: scopes, resource, audience, etc.
	SetUserinfoFromTokenExchangeRequest(ctx context.Context, userinfo *oidc.UserInfo, request TokenExchangeRequest) error
}

type TokenExchangeTokensVerifierStorage

type TokenExchangeTokensVerifierStorage interface {
	VerifyExchangeSubjectToken(ctx context.Context, token string, tokenType oidc.TokenType) (tokenIDOrToken string, subject string, tokenClaims map[string]any, err error)
	VerifyExchangeActorToken(ctx context.Context, token string, tokenType oidc.TokenType) (tokenIDOrToken string, actor string, tokenClaims map[string]any, err error)
}

TokenExchangeTokensVerifierStorage is an optional interface used in token exchange process to verify tokens issued by third-party applications. If interface is not implemented - only tokens issued by op will be exchanged.

type TokenRequest

type TokenRequest interface {
	GetSubject() string
	GetAudience() []string
	GetScopes() []string
}

type UnimplementedServer

type UnimplementedServer struct{}

func (UnimplementedServer) Authorize

func (UnimplementedServer) ClientCredentialsExchange

func (UnimplementedServer) CodeExchange

func (UnimplementedServer) DeviceAuthorization

func (UnimplementedServer) DeviceToken

func (UnimplementedServer) Discovery

func (UnimplementedServer) Discovery(ctx context.Context, r *Request[struct{}]) (*Response, error)

func (UnimplementedServer) EndSession

func (UnimplementedServer) Health

func (UnimplementedServer) Health(ctx context.Context, r *Request[struct{}]) (*Response, error)

func (UnimplementedServer) Introspect

func (UnimplementedServer) JWTProfile

func (UnimplementedServer) Keys

func (UnimplementedServer) Keys(ctx context.Context, r *Request[struct{}]) (*Response, error)

func (UnimplementedServer) Ready

func (UnimplementedServer) Ready(ctx context.Context, r *Request[struct{}]) (*Response, error)

func (UnimplementedServer) RefreshToken

func (UnimplementedServer) Revocation

func (UnimplementedServer) TokenExchange

func (UnimplementedServer) UserInfo

func (UnimplementedServer) VerifyAuthRequest

func (UnimplementedServer) VerifyClient

type UserCodeConfig

type UserCodeConfig struct {
	CharSet      string
	CharAmount   int
	DashInterval int
}

type UserinfoProvider

type UserinfoProvider interface {
	Decoder() httphelper.Decoder
	Crypto() Crypto
	Storage() Storage
	AccessTokenVerifier(context.Context) *AccessTokenVerifier
}

Directories

Path Synopsis
Package mock is a generated GoMock package.
Package mock is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL