Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrClientNotTrusted = errors.New("federation broker is only available to trusted clients")
ErrClientNotTrusted is returned when the requesting OAuth client is not permitted to use the federation broker.
Functions ¶
func SetStateCookie ¶
func SetStateCookie(w http.ResponseWriter, sessionKey string) error
func ValidateStateCookie ¶
Types ¶
type Broker ¶
type Broker struct {
// contains filtered or unexported fields
}
Broker manages both legs of the federation flow:
- Initiate: validates the client, parks the AuthorizeRequest, and returns the external IdP authorization URL.
- ConsumeSession: retrieves and deletes the session so the caller can issue an authorization code for the user it has just resolved. Deletes the session so it cannot be reused.
func NewBroker ¶
func NewBroker( providerStore ProviderLookup, sessionRepo SessionRepository, clientManager ClientLookup, baseURL url.URL, ) *Broker
func (*Broker) ConsumeSession ¶ added in v1.0.8
func (*Broker) Initiate ¶
func (b *Broker) Initiate(ctx context.Context, ar fosite.AuthorizeRequester) (authURL string, sessionKey string, err error)
Initiate checks that the requesting client is trusted, parks the AuthorizeRequest in the database, and returns the external IdP authorization URL together with the session key.
The session key is a server-generated random string stored as federated_sessions.key and sent to the external IdP as the OAuth state parameter. The caller must persist it in a cookie (via SetStateCookie) before redirecting the user, so that it can be verified against the state returned in the callback.
The client-controlled ar.GetState() is never used as the session key to avoid collision and replay risks.
type ClientData ¶
type ClientData struct {
ClientID string `json:"client_id"`
RedirectURI string `json:"redirect_uri"`
Scopes []string `json:"scopes"`
Nonce string `json:"nonce"`
CodeChallenge string `json:"code_challenge"`
CodeChallengeMethod string `json:"code_challenge_method"`
ProviderHint string `json:"provider_hint"`
ResponseTypes []string `json:"response_types"`
}
type ClientLookup ¶
type ClientLookup interface {
GetClient(ctx context.Context, clientID string) (*clients.Client, error)
}
ClientLookup is the subset of clients.Registry the broker needs.
type ProviderLookup ¶
ProviderLookup is the subset of ProviderStore the broker needs.
type Repository ¶
type Repository struct {
// contains filtered or unexported fields
}
func NewRepository ¶
func NewRepository(db querier) *Repository
func (*Repository) Delete ¶
func (r *Repository) Delete(ctx context.Context, sessionKey string) error
func (*Repository) FindBySessionKey ¶
type Session ¶
type Session struct {
ClientData
Key string `db:"key"`
RequestedState string `db:"requested_state"`
CreatedAt time.Time `db:"created_at"`
ExpiresAt time.Time `db:"expires_at"`
UserInfo *identity.UserInfo `db:"user_info"`
}
func NewSession ¶
func NewSession(key, requestedState string, clientData *ClientData, createdAt, expiresAt time.Time) *Session
func NewSessionFromAuthorizeRequest ¶
func NewSessionFromAuthorizeRequest(key string, ar fosite.AuthorizeRequester) (*Session, error)
type SessionRepository ¶
type SessionRepository interface {
Create(ctx context.Context, session Session) (*Session, error)
FindBySessionKey(ctx context.Context, sessionKey string) (*Session, bool, error)
Delete(ctx context.Context, sessionKey string) error
}
SessionRepository interface allows injecting a mock Repository in tests