Documentation
¶
Overview ¶
Package rp logs people in with OpenID Connect: it is the relying-party half that go-authn/oidc deliberately leaves out.
p, err := rp.Discover(ctx, http.DefaultClient, "https://login.example.org")
c, err := rp.NewClient(ctx, p, rp.Config{ClientID: "console", RedirectURI: redirect})
f := rp.NewFlow()
http.Redirect(w, r, c.AuthCodeURL(f, nil), http.StatusFound)
// ... at the redirect URI, with the flow found again:
tok, id, err := c.Exchange(ctx, code, f)
// ... later, a token for one resource server (RFC 8707 §2.2):
at, err := c.Refresh(ctx, tok.RefreshToken, rp.For{Resource: "https://fs-a.example.org/"})
What it always does, because each is a defence somebody once skipped:
- PKCE with S256 (RFC 7636), for confidential clients too (RFC 9700 §2.1.1), and a provider that publishes its methods without S256 is refused at discovery: it would ignore the challenge.
- A state and a nonce per login. The ID token is verified -- signature, issuer, audience, times, by go-authn/oidc -- and must carry this login's nonce; with several audiences, azp must be this client.
- The discovery document must name the issuer it was fetched for, exactly (OIDC Discovery §4.3), and every endpoint must be https or loopback.
A native application uses Loopback, which runs the whole login through the system browser and a listener on 127.0.0.1 (RFC 8252). Such a client is public: a secret shipped inside an application is no secret (RFC 8252 §8.5).
Index ¶
- func Challenge(verifier string) string
- func IsInvalidGrant(err error) bool
- func Loopback(ctx context.Context, p *Provider, cfg Config, open func(string) error, ...) (*Client, *Token, *oidc.Token, error)
- func OpenBrowser(u string) error
- type Client
- func (c *Client) AuthCodeURL(f Flow, extra url.Values) string
- func (c *Client) EndSessionURL(postLogout string) string
- func (c *Client) Exchange(ctx context.Context, code string, f Flow) (*Token, *oidc.Token, error)
- func (c *Client) Provider() *Provider
- func (c *Client) Refresh(ctx context.Context, refreshToken string, f For) (*Token, error)
- func (c *Client) VerifyID(ctx context.Context, raw, nonce string) (*oidc.Token, error)
- type Config
- type Error
- type Flow
- type For
- type Provider
- type Token
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsInvalidGrant ¶
IsInvalidGrant says whether err is the provider ending the grant.
func Loopback ¶
func Loopback(ctx context.Context, p *Provider, cfg Config, open func(string) error, extra url.Values) (*Client, *Token, *oidc.Token, error)
Loopback logs a person in from a native application, as RFC 8252 says to:
- it listens on the loopback IP literal, 127.0.0.1, or [::1] when there is no IPv4 loopback, on a port the system picks (§7.3); never on "localhost" (§8.3), and on no other interface;
- it opens the authorization URL in the system browser with open -- never a web view inside the application (§8.12) -- and PKCE protects the code on its way back (§6);
- it waits for the redirect at http://127.0.0.1:<port>/callback until ctx ends. A request whose state is not this login's is answered 400 and ignored -- any local process can reach the port -- so only the provider's answer ends the wait.
cfg.RedirectURI is set here; leave it empty. A native app is a public client (cfg.Secret empty, §8.5); go-authn/bridge accepts any loopback port for a client registered with http://127.0.0.1/callback. extra adds authorization parameters, such as RFC 8707 resources.
It returns the client (to refresh with), the tokens, and the verified ID token.
func OpenBrowser ¶
OpenBrowser opens u in the system's default browser.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client logs people in at one provider.
func NewClient ¶
NewClient is a client of p. It reads the provider's keys now, to verify ID tokens with.
func (*Client) AuthCodeURL ¶
AuthCodeURL is where to send the browser. extra adds parameters, such as RFC 8707 resource indicators or a prompt.
func (*Client) EndSessionURL ¶
EndSessionURL is where to send a browser to end the session at the provider too (OIDC RP-Initiated Logout §2), or "" when it has no such endpoint.
func (*Client) Exchange ¶
Exchange trades the code the redirect brought for tokens, and verifies the ID token against the flow's nonce.
func (*Client) Refresh ¶
Refresh buys an access token with a refresh token. A provider that rotates refresh tokens returns a new one, and revokes the whole grant when a retired one comes back (RFC 9700 §4.14.2): keep the new one, and never refresh twice at once with the same.
func (*Client) VerifyID ¶
VerifyID checks an ID token: signature, issuer, audience (this client), times -- go-authn/oidc -- and the nonce of the login it answers, so that an ID token from another login cannot be played into this one (OIDC Core §3.1.3.7). With several audiences, azp must be this client.
type Config ¶
type Config struct {
ClientID string
// Secret is a confidential client's, sent with client_secret_basic
// (RFC 6749 §2.3.1). Empty is a PUBLIC client: its client_id goes in the
// token request instead, as a native app's must (RFC 8252 §8.5).
Secret string
RedirectURI string
// Scopes asked for at the login. Default openid. A refresh token usually
// needs offline_access, or the provider's equivalent.
Scopes []string
}
Config is a client of a provider.
type Error ¶
Error is the provider's refusal (RFC 6749 §5.2). invalid_grant means the grant is over and the person has to log in again; invalid_target, that a resource was refused (RFC 8707 §2).
type Flow ¶
type Flow struct {
State, Nonce, Verifier string
}
A Flow is one login in progress: what the redirect must be checked against and the code exchanged with. Keep it where only this browser can bring it back -- a sealed cookie, or the memory of the native app that started it.
type For ¶
For names what a refreshed token is for: a resource server (RFC 8707 §2.2: the token is for that one, the refresh token keeps the whole grant), and/or a scope, for a provider that sets the audience from a scope.