fositeフレームワークが提供するAPI
OAuth2Provider
自らOAuth2のhttpハンドラーを実装する人向けにfositeが提供しているinterface
interface定義は大別して5つのグループに分けられる。
interface定義
type OAuth2Provider interface {
NewAuthorizeRequest(ctx context.Context, req *http.Request) (AuthorizeRequester, error)
NewAuthorizeResponse(ctx context.Context, requester AuthorizeRequester, session Session) (AuthorizeResponder, error)
WriteAuthorizeError(ctx context.Context, rw http.ResponseWriter, requester AuthorizeRequester, err error)
WriteAuthorizeResponse(ctx context.Context, rw http.ResponseWriter, requester AuthorizeRequester, responder AuthorizeResponder)
NewAccessRequest(ctx context.Context, req *http.Request, session Session) (AccessRequester, error)
NewAccessResponse(ctx context.Context, requester AccessRequester) (AccessResponder, error)
WriteAccessError(ctx context.Context, rw http.ResponseWriter, requester AccessRequester, err error)
WriteAccessResponse(ctx context.Context, rw http.ResponseWriter, requester AccessRequester, responder AccessResponder)
NewRevocationRequest(ctx context.Context, r *http.Request) error
WriteRevocationResponse(ctx context.Context, rw http.ResponseWriter, err error)
IntrospectToken(ctx context.Context, token string, tokenUse TokenUse, session Session, scope ...string) (TokenUse, AccessRequester, error)
NewIntrospectionRequest(ctx context.Context, r *http.Request, session Session) (IntrospectionResponder, error)
WriteIntrospectionError(ctx context.Context, rw http.ResponseWriter, err error)
WriteIntrospectionResponse(ctx context.Context, rw http.ResponseWriter, r IntrospectionResponder)
NewPushedAuthorizeRequest(ctx context.Context, r *http.Request) (AuthorizeRequester, error)
NewPushedAuthorizeResponse(ctx context.Context, ar AuthorizeRequester, session Session) (PushedAuthorizeResponder, error)
WritePushedAuthorizeResponse(ctx context.Context, rw http.ResponseWriter, ar AuthorizeRequester, resp PushedAuthorizeResponder)
WritePushedAuthorizeError(ctx context.Context, rw http.ResponseWriter, ar AuthorizeRequester, err error)
}
PushedAuthorize
はひとまず置いておくと、上から
- 認可エンドポイント
- トークンエンドポイント
- revokeエンドポイント
- introspectエンドポイント
に分けることができる
oauth2.go
で定義されている。
自らOAuth2のhttpハンドラーを実装する人はFosite
型をインスタンス化して使うことになるが、このOAuth2Provider
インターフェースの具象型としてFosite
を取り扱うことになる。
FositeとOAuth2Providerのインスタンス化
// compose/compose.go
func Compose(config *fosite.Config, storage interface{}, strategy interface{}, factories ...Factory) fosite.OAuth2Provider {
// ここでFositeを作る
f := fosite.NewOAuth2Provider(storage.(fosite.Storage), config)
for _, factory := range factories {
res := factory(config, storage, strategy)
if ah, ok := res.(fosite.AuthorizeEndpointHandler); ok {
config.AuthorizeEndpointHandlers.Append(ah)
}
if th, ok := res.(fosite.TokenEndpointHandler); ok {
config.TokenEndpointHandlers.Append(th)
}
if tv, ok := res.(fosite.TokenIntrospector); ok {
config.TokenIntrospectionHandlers.Append(tv)
}
if rh, ok := res.(fosite.RevocationHandler); ok {
config.RevocationHandlers.Append(rh)
}
if ph, ok := res.(fosite.PushedAuthorizeEndpointHandler); ok {
config.PushedAuthorizeEndpointHandlers.Append(ph)
}
}
return f // 返り値の型はfosite.OAuth2Provider
}
// fosite.go
func NewOAuth2Provider(s Storage, c Configurator) *Fosite {
return &Fosite{Store: s, Config: c}
}
Fosite
fositeフレームワークを使う場合はこの型をインスタンス化して使う。
fosite.go
で定義されている
構造体定義
var _ OAuth2Provider = (*Fosite)(nil)
type Fosite struct {
Store Storage
Config Configurator
}
Store
とConfig
だけを保持している。また、Fosite
型はOAuth2Provider
インターフェースを満たしている。
Config
config_default.go
で定義されている
この型を通してfositeはフレームワークとして提供する機能にアクセスする
下記のように、提供するhttpハンドラーもここに内包されている
// AuthorizeEndpointHandlers is a list of handlers that are called before the authorization endpoint is served.
AuthorizeEndpointHandlers AuthorizeEndpointHandlers
// TokenEndpointHandlers is a list of handlers that are called before the token endpoint is served.
TokenEndpointHandlers TokenEndpointHandlers
// TokenIntrospectionHandlers is a list of handlers that are called before the token introspection endpoint is served.
TokenIntrospectionHandlers TokenIntrospectionHandlers
// RevocationHandlers is a list of handlers that are called before the revocation endpoint is served.
RevocationHandlers RevocationHandlers
// PushedAuthorizeEndpointHandlers is a list of handlers that are called before the PAR endpoint is served.
PushedAuthorizeEndpointHandlers PushedAuthorizeEndpointHandlers
構造体定義
type Config struct {
// AccessTokenLifespan sets how long an access token is going to be valid. Defaults to one hour.
AccessTokenLifespan time.Duration
// RefreshTokenLifespan sets how long a refresh token is going to be valid. Defaults to 30 days. Set to -1 for
// refresh tokens that never expire.
RefreshTokenLifespan time.Duration
// AuthorizeCodeLifespan sets how long an authorize code is going to be valid. Defaults to fifteen minutes.
AuthorizeCodeLifespan time.Duration
// IDTokenLifespan sets the default id token lifetime. Defaults to one hour.
IDTokenLifespan time.Duration
// IDTokenIssuer sets the default issuer of the ID Token.
IDTokenIssuer string
// HashCost sets the cost of the password hashing cost. Defaults to 12.
HashCost int
// DisableRefreshTokenValidation sets the introspection endpoint to disable refresh token validation.
DisableRefreshTokenValidation bool
// SendDebugMessagesToClients if set to true, includes error debug messages in response payloads. Be aware that sensitive
// data may be exposed, depending on your implementation of Fosite. Such sensitive data might include database error
// codes or other information. Proceed with caution!
SendDebugMessagesToClients bool
// ScopeStrategy sets the scope strategy that should be supported, for example fosite.WildcardScopeStrategy.
ScopeStrategy ScopeStrategy
// AudienceMatchingStrategy sets the audience matching strategy that should be supported, defaults to fosite.DefaultsAudienceMatchingStrategy.
AudienceMatchingStrategy AudienceMatchingStrategy
// EnforcePKCE, if set to true, requires clients to perform authorize code flows with PKCE. Defaults to false.
EnforcePKCE bool
// EnforcePKCEForPublicClients requires only public clients to use PKCE with the authorize code flow. Defaults to false.
EnforcePKCEForPublicClients bool
// EnablePKCEPlainChallengeMethod sets whether or not to allow the plain challenge method (S256 should be used whenever possible, plain is really discouraged). Defaults to false.
EnablePKCEPlainChallengeMethod bool
// AllowedPromptValues sets which OpenID Connect prompt values the server supports. Defaults to []string{"login", "none", "consent", "select_account"}.
AllowedPromptValues []string
// TokenURL is the the URL of the Authorization Server's Token Endpoint. If the authorization server is intended
// to be compatible with the private_key_jwt client authentication method (see http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth),
// this value MUST be set.
TokenURL string
// JWKSFetcherStrategy is responsible for fetching JSON Web Keys from remote URLs. This is required when the private_key_jwt
// client authentication method is used. Defaults to fosite.DefaultJWKSFetcherStrategy.
JWKSFetcherStrategy JWKSFetcherStrategy
// TokenEntropy indicates the entropy of the random string, used as the "message" part of the HMAC token.
// Defaults to 32.
TokenEntropy int
// RedirectSecureChecker is a function that returns true if the provided URL can be securely used as a redirect URL.
RedirectSecureChecker func(context.Context, *url.URL) bool
// RefreshTokenScopes defines which OAuth scopes will be given refresh tokens during the authorization code grant exchange. This defaults to "offline" and "offline_access". When set to an empty array, all exchanges will be given refresh tokens.
RefreshTokenScopes []string
// MinParameterEntropy controls the minimum size of state and nonce parameters. Defaults to fosite.MinParameterEntropy.
MinParameterEntropy int
// UseLegacyErrorFormat controls whether the legacy error format (with `error_debug`, `error_hint`, ...)
// should be used or not.
UseLegacyErrorFormat bool
// GrantTypeJWTBearerCanSkipClientAuth indicates, if client authentication can be skipped, when using jwt as assertion.
GrantTypeJWTBearerCanSkipClientAuth bool
// GrantTypeJWTBearerIDOptional indicates, if jti (JWT ID) claim required or not in JWT.
GrantTypeJWTBearerIDOptional bool
// GrantTypeJWTBearerIssuedDateOptional indicates, if "iat" (issued at) claim required or not in JWT.
GrantTypeJWTBearerIssuedDateOptional bool
// GrantTypeJWTBearerMaxDuration sets the maximum time after JWT issued date, during which the JWT is considered valid.
GrantTypeJWTBearerMaxDuration time.Duration
// ClientAuthenticationStrategy indicates the Strategy to authenticate client requests
ClientAuthenticationStrategy ClientAuthenticationStrategy
// ResponseModeHandlerExtension provides a handler for custom response modes
ResponseModeHandlerExtension ResponseModeHandler
// MessageCatalog is the message bundle used for i18n
MessageCatalog i18n.MessageCatalog
// FormPostHTMLTemplate sets html template for rendering the authorization response when the request has response_mode=form_post.
FormPostHTMLTemplate *template.Template
// OmitRedirectScopeParam indicates whether the "scope" parameter should be omitted from the redirect URL.
OmitRedirectScopeParam bool
// SanitationWhiteList is a whitelist of form values that are required by the token endpoint. These values
// are safe for storage in a database (cleartext).
SanitationWhiteList []string
// JWTScopeClaimKey defines the claim key to be used to set the scope in. Valid fields are "scope" or "scp" or both.
JWTScopeClaimKey jwt.JWTScopeFieldEnum
// AccessTokenIssuer is the issuer to be used when generating access tokens.
AccessTokenIssuer string
// ClientSecretsHasher is the hasher used to hash OAuth2 Client Secrets.
ClientSecretsHasher Hasher
// HTTPClient is the HTTP client to use for requests.
HTTPClient *retryablehttp.Client
// AuthorizeEndpointHandlers is a list of handlers that are called before the authorization endpoint is served.
AuthorizeEndpointHandlers AuthorizeEndpointHandlers
// TokenEndpointHandlers is a list of handlers that are called before the token endpoint is served.
TokenEndpointHandlers TokenEndpointHandlers
// TokenIntrospectionHandlers is a list of handlers that are called before the token introspection endpoint is served.
TokenIntrospectionHandlers TokenIntrospectionHandlers
// RevocationHandlers is a list of handlers that are called before the revocation endpoint is served.
RevocationHandlers RevocationHandlers
// PushedAuthorizeEndpointHandlers is a list of handlers that are called before the PAR endpoint is served.
PushedAuthorizeEndpointHandlers PushedAuthorizeEndpointHandlers
// GlobalSecret is the global secret used to sign and verify signatures.
GlobalSecret []byte
// RotatedGlobalSecrets is a list of global secrets that are used to verify signatures.
RotatedGlobalSecrets [][]byte
// HMACHasher is the hasher used to generate HMAC signatures.
HMACHasher func() hash.Hash
// PushedAuthorizeRequestURIPrefix is the URI prefix for the PAR request_uri.
// This is defaulted to 'urn:ietf:params:oauth:request_uri:'.
PushedAuthorizeRequestURIPrefix string
// PushedAuthorizeContextLifespan is the lifespan of the PAR context
PushedAuthorizeContextLifespan time.Duration
// IsPushedAuthorizeEnforced enforces pushed authorization request for /authorize
IsPushedAuthorizeEnforced bool
}
Configurator
Config
のメンバーにアクセスするためのinterfaceを提供している。
interface定義
type Configurator interface {
IDTokenIssuerProvider
IDTokenLifespanProvider
AllowedPromptsProvider
EnforcePKCEProvider
EnforcePKCEForPublicClientsProvider
EnablePKCEPlainChallengeMethodProvider
GrantTypeJWTBearerCanSkipClientAuthProvider
GrantTypeJWTBearerIDOptionalProvider
GrantTypeJWTBearerIssuedDateOptionalProvider
GetJWTMaxDurationProvider
AudienceStrategyProvider
ScopeStrategyProvider
RedirectSecureCheckerProvider
OmitRedirectScopeParamProvider
SanitationAllowedProvider
JWTScopeFieldProvider
AccessTokenIssuerProvider
DisableRefreshTokenValidationProvider
RefreshTokenScopesProvider
AccessTokenLifespanProvider
RefreshTokenLifespanProvider
AuthorizeCodeLifespanProvider
TokenEntropyProvider
RotatedGlobalSecretsProvider
GlobalSecretProvider
JWKSFetcherStrategyProvider
HTTPClientProvider
ScopeStrategyProvider
AudienceStrategyProvider
MinParameterEntropyProvider
HMACHashingProvider
ClientAuthenticationStrategyProvider
ResponseModeHandlerExtensionProvider
SendDebugMessagesToClientsProvider
JWKSFetcherStrategyProvider
ClientAuthenticationStrategyProvider
ResponseModeHandlerExtensionProvider
MessageCatalogProvider
FormPostHTMLTemplateProvider
TokenURLProvider
GetSecretsHashingProvider
AuthorizeEndpointHandlersProvider
TokenEndpointHandlersProvider
TokenIntrospectionHandlersProvider
RevocationHandlersProvider
UseLegacyErrorFormatProvider
}
Configurator
の中でさらに別interface定義が使われているのは、Config
を使う箇所によってアクセスできるメンバーを制限するためだ。
例えば下記の例ようにHandler
の中ではGetBarにアクセスできないようになっている
Configuratorの利点
package main
import "fmt"
type (
FooProvider interface {
GetFoo() string
}
BarProvider interface {
GetBar() string
}
Configurator interface {
FooProvider
BarProvider
}
)
var _ Configurator = (*Config)(nil)
type Config struct {
Foo string
Bar string
}
func (c *Config) GetFoo() string { return c.Foo }
func (c *Config) GetBar() string { return c.Bar }
type Handler struct {
Config interface {
FooProvider
}
}
func main() {
cfg := &Config{Foo: "foo", Bar: "bar"}
handler := Handler{Config: cfg}
fmt.Println(handler.Config.GetFoo())
//fmt.Println(handler.Config.GetBar()) // エラー
}