Documentation
¶
Overview ¶
Package deviceflow implements the RFC 8628 OAuth 2.0 Device Authorization Grant's token-endpoint handler.
Index ¶
- Variables
- func Factory(deviceStorage authstorage.DeviceCodeStorage, minInterval time.Duration) server.Factory
- type Handler
- func (*Handler) CanHandleTokenEndpointRequest(_ context.Context, requester fosite.AccessRequester) bool
- func (*Handler) CanSkipClientAuth(_ context.Context, _ fosite.AccessRequester) bool
- func (h *Handler) HandleTokenEndpointRequest(ctx context.Context, requester fosite.AccessRequester) error
- func (h *Handler) PopulateTokenEndpointResponse(ctx context.Context, requester fosite.AccessRequester, ...) error
Constants ¶
This section is empty.
Variables ¶
var ErrAuthorizationPending = &fosite.RFC6749Error{ ErrorField: "authorization_pending", DescriptionField: "The authorization request is still pending as the end user hasn't yet completed the user-interaction steps.", CodeField: http.StatusBadRequest, }
ErrAuthorizationPending indicates the device flow is still awaiting the end user's action at the verification URI (RFC 8628 Section 3.5).
var ErrExpiredToken = &fosite.RFC6749Error{ ErrorField: "expired_token", DescriptionField: "The device_code has expired. The client must restart the device authorization flow.", CodeField: http.StatusBadRequest, }
ErrExpiredToken indicates the device_code has expired and the client must restart the device authorization flow (RFC 8628 Section 3.5).
This is deliberately its own sentinel rather than a reuse of fosite's fosite.ErrTokenExpired: that error's wire "error" field is "invalid_token" (RFC 6750 Section 3.1's bearer-token-error vocabulary), not RFC 8628 Section 3.5's "expired_token". Reusing it would emit the wrong error code to device-flow clients.
var ErrSlowDown = &fosite.RFC6749Error{ ErrorField: "slow_down", DescriptionField: "The client polled the token endpoint faster than the interval permitted.", CodeField: http.StatusBadRequest, }
ErrSlowDown indicates the client polled faster than the granted interval (RFC 8628 Section 3.5).
Functions ¶
func Factory ¶
func Factory(deviceStorage authstorage.DeviceCodeStorage, minInterval time.Duration) server.Factory
Factory returns a server.Factory that registers the RFC 8628 device-code grant, mirroring how the tokenexchange and jwtbearer factories are constructed in server_impl.go's buildProvider.
Types ¶
type Handler ¶
type Handler struct {
DeviceStorage authstorage.DeviceCodeStorage
CoreStorage oauth2.CoreStorage
Strategy oauth2.CoreStrategy
Config deviceFlowConfig
// MinInterval is the minimum time a client must wait between polls
// (RFC 8628 Section 3.5). A poll that arrives sooner is rejected with
// slow_down.
MinInterval time.Duration
}
Handler implements fosite's TokenEndpointHandler for RFC 8628's urn:ietf:params:oauth:grant-type:device_code grant.
A device_code is single-use: HandleTokenEndpointRequest deletes it from DeviceStorage as soon as it observes DeviceRequestStatusAuthorized, before PopulateTokenEndpointResponse ever issues a token, so a device_code can never be redeemed twice.
func (*Handler) CanHandleTokenEndpointRequest ¶
func (*Handler) CanHandleTokenEndpointRequest(_ context.Context, requester fosite.AccessRequester) bool
CanHandleTokenEndpointRequest returns true if the request's grant_type is the RFC 8628 device_code grant type.
func (*Handler) CanSkipClientAuth ¶
CanSkipClientAuth always returns false: the device_code grant does not exempt the client from standard authentication. The client authenticates with whatever method it registered with, exactly as for every other grant; only grants that attach a synthetic, unregistered client (see storage.NewSyntheticClient) skip authentication, and this is not one of them.
func (*Handler) HandleTokenEndpointRequest ¶
func (h *Handler) HandleTokenEndpointRequest(ctx context.Context, requester fosite.AccessRequester) error
HandleTokenEndpointRequest validates the device_code, enforces the RFC 8628 polling contract (slow_down, authorization_pending, access_denied, expired_token), and — once the device request has been authorized — attaches a session and consumes (deletes) the device_code so it cannot be redeemed twice.
func (*Handler) PopulateTokenEndpointResponse ¶
func (h *Handler) PopulateTokenEndpointResponse( ctx context.Context, requester fosite.AccessRequester, responder fosite.AccessResponder, ) error
PopulateTokenEndpointResponse issues the access token and, when the client is registered for the refresh_token grant, a refresh token.