Documentation
¶
Overview ¶
Package oauth talks to external identity providers (Google, Microsoft, Apple): the authorize URL, the code exchange, the verification of ID tokens and Apple's client secret. It knows nothing of users or sessions.
Everything it sends goes through an HTTP client that dials only the provider's own hosts, resolves them itself and refuses private, loopback and link-local addresses, so a mistake in configuration can't make backd reach inside the network.
Index ¶
- Variables
- func BuiltinHostAllowed(host string) bool
- func NewClient(allowed func(host string) bool, allowPrivate bool) *http.Client
- func UsesPKCE(p *registry.Provider) bool
- type AuthorizeParams
- type Claims
- type Endpoints
- type Service
- func (s *Service) AppleClientSecret(p *registry.Provider, clientID, privateKeyPEM string) (string, error)
- func (s *Service) AuthorizeURL(p *registry.Provider, a AuthorizeParams) string
- func (s *Service) Exchange(ctx context.Context, p *registry.Provider, ...) (Tokens, error)
- func (s *Service) Revoke(ctx context.Context, p *registry.Provider, ...) error
- func (s *Service) Subject(ctx context.Context, p *registry.Provider, idToken string, native bool) (subject, audience string, err error)
- func (s *Service) Verify(ctx context.Context, p *registry.Provider, idToken, nonce string, native bool) (Claims, error)
- type Tokens
Constants ¶
This section is empty.
Variables ¶
var ( // ErrExchange: the provider refused the authorization code. ErrExchange = errors.New("oauth: the provider refused the authorization code") // ErrInvalidToken: an ID token that does not verify (signature, issuer, // audience, expiry or nonce), or is missing what is needed. ErrInvalidToken = errors.New("oauth: the ID token is not valid") ErrUnavailable = errors.New("oauth: the provider is not available") )
Errors a provider's answers can lead to. None of them carries anything the provider said beyond its own error code.
var BuiltinHosts = map[string][]string{
"google": {"accounts.google.com", "oauth2.googleapis.com", "www.googleapis.com"},
"microsoft": {"login.microsoftonline.com"},
"apple": {"appleid.apple.com"},
}
BuiltinHosts are the hosts of each built-in provider.
var ErrHostNotAllowed = errors.New("oauth: the host is not one of the provider's")
ErrHostNotAllowed means a request named a host that is not one of the provider's.
Functions ¶
func BuiltinHostAllowed ¶
BuiltinHostAllowed accepts the hosts of the built-in providers.
Types ¶
type AuthorizeParams ¶
type AuthorizeParams struct {
RedirectURI string
State string
Nonce string
CodeChallenge string // PKCE (S256) between backd and the provider; empty: none
}
AuthorizeParams are what an authorization request carries.
type Claims ¶
type Claims struct {
// Subject identifies the person for the provider: sub, or for Microsoft the tenant
// and object ids, so the same person in two tenants is two identities.
Subject string
Email string
EmailVerified bool
Name string
GivenName string
FamilyName string
Picture string
// Audience is the client id the token was issued to (the web client's, or a native app's).
Audience string
}
Claims are what backd takes from a verified ID token.
type Endpoints ¶
type Endpoints struct {
Authorize, Token, JWKS, Revoke string
}
Endpoints are the URLs of a provider.
func BuiltinEndpoints ¶
BuiltinEndpoints are the endpoints of the built-in providers.
type Service ¶
type Service struct {
// HTTP reaches the providers: NewClient(BuiltinHostAllowed, …) in production.
HTTP *http.Client
// Endpoints gives a provider's URLs; BuiltinEndpoints when nil.
Endpoints func(*registry.Provider) Endpoints
// Now is the clock; time.Now when nil.
Now func() time.Time
// contains filtered or unexported fields
}
Service is what the sign-in flow asks of providers.
func (*Service) AppleClientSecret ¶
func (s *Service) AppleClientSecret(p *registry.Provider, clientID, privateKeyPEM string) (string, error)
AppleClientSecret returns the client secret to send to Apple for the provider and the client id it acts as (the Services ID, or an app's bundle id), signed with the private key (the .p8 file's PEM). It is cached and renewed before it expires.
func (*Service) AuthorizeURL ¶
func (s *Service) AuthorizeURL(p *registry.Provider, a AuthorizeParams) string
AuthorizeURL is where to send the user to sign in with the provider.
func (*Service) Exchange ¶
func (s *Service) Exchange(ctx context.Context, p *registry.Provider, clientID, secret, code, redirectURI, codeVerifier string) (Tokens, error)
Exchange trades an authorization code for the user's ID token. clientID is the application the code was issued to (the provider's web client, or for a native app its own id), and secret the client secret of Google or Microsoft, or Apple's already-signed one.
func (*Service) Revoke ¶
func (s *Service) Revoke(ctx context.Context, p *registry.Provider, clientID, clientSecret, refreshToken string) error
Revoke tells Apple to revoke a refresh token, which ends the user's link between the app and their Apple ID. clientID is the one the token was issued to. A token Apple no longer knows counts as revoked.
func (*Service) Subject ¶
func (s *Service) Subject(ctx context.Context, p *registry.Provider, idToken string, native bool) (subject, audience string, err error)
Subject verifies an ID token like Verify, except for the nonce (the one the code exchange gives back has none), and returns who it is for: the subject and the client id it was issued to. It is how backd checks that an authorization code and the ID token a native app sent belong to the same person.
func (*Service) Verify ¶
func (s *Service) Verify(ctx context.Context, p *registry.Provider, idToken, nonce string, native bool) (Claims, error)
Verify checks an ID token of the provider and returns what it says about the user: its signature against the provider's keys, issuer, audience (the web client's, and, when native, the mobile apps'), expiry and nonce. nonce is what the token must carry (exactly, or, when native, also as its SHA-256 in hex or base64url, as the platform sign-in SDKs put it).
Directories
¶
| Path | Synopsis |
|---|---|
|
Package oauthtest is a small identity provider for tests: it signs ID tokens with its own key, publishes them, and plays the parts of a provider's authorize, token and keys endpoints, so the sign-in flow can be run end to end without a real one.
|
Package oauthtest is a small identity provider for tests: it signs ID tokens with its own key, publishes them, and plays the parts of a provider's authorize, token and keys endpoints, so the sign-in flow can be run end to end without a real one. |