Documentation
¶
Overview ¶
Package oidc implements OpenID Connect client logic for the golang.org/x/oauth2 package.
provider, err := oidc.NewProvider(ctx, "https://accounts.example.com")
if err != nil {
return err
}
// Configure an OpenID Connect aware OAuth2 client.
oauth2Config := oauth2.Config{
ClientID: clientID,
ClientSecret: clientSecret,
RedirectURL: redirectURL,
Endpoint: provider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
}
OAuth2 redirects are unchanged.
func handleRedirect(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, oauth2Config.AuthCodeURL(state), http.StatusFound)
})
For callbacks the provider can be used to query for user information such as email.
func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
// Verify state...
oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
if err != nil {
http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
return
}
userinfo, err := provider.UserInfo(ctx, oauth2.StaticTokenSource(oauth2Token))
if err != nil {
http.Error(w, "Failed to get userinfo: "+err.Error(), http.StatusInternalServerError)
return
}
// ...
})
The provider also has the ability to verify ID Tokens.
verifier := provider.NewVerifier(ctx)
The returned verifier can be used to perform basic validation on ID Token issued by the provider, including verifying the JWT signature. It then returns the payload.
func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
// Verify state...
oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
if err != nil {
http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
return
}
// Extract the ID Token from oauth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
http.Error(w, "No ID Token found", http.StatusInternalServerError)
return
}
// Verify that the ID Token is signed by the provider.
idToken, err := verifier.Verify(rawIDToken)
if err != nil {
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
return
}
// Unmarshal ID Token for expected custom claims.
var claims struct {
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
}
if err := idToken.Claims(&claims); err != nil {
http.Error(w, "Failed to unmarshal ID Token custom claims: "+err.Error(), http.StatusInternalServerError)
return
}
// ...
})
ID Token nonces are supported.
First, provide a nonce source for nonce validation. This will then be used to wrap the existing provider ID Token verifier.
// A verifier which boths verifies the ID Token signature and nonce. nonceEnabledVerifier := provider.NewVerifier(ctx, oidc.VerifyNonce(nonceSource))
For the redirect provide a nonce auth code option. This will be placed as a URL parameter during the client redirect.
func handleRedirect(w http.ResponseWriter, r *http.Request) {
nonce, err := newNonce()
if err != nil {
// ...
}
// Provide a nonce for the OpenID Connect ID Token.
http.Redirect(w, r, oauth2Config.AuthCodeURL(state, oidc.Nonce(nonce)), http.StatusFound)
})
The nonce enabled verifier can then be used to verify the nonce while unpacking the ID Token.
func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
// Verify state...
oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
if err != nil {
http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
return
}
// Extract the ID Token from oauth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
http.Error(w, "No ID Token found", http.StatusInternalServerError)
return
}
// Verify that the ID Token is signed by the provider and verify the nonce.
idToken, err := nonceEnabledVerifier.Verify(rawIDToken)
if err != nil {
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
return
}
// Continue as above...
})
This package uses contexts to derive HTTP clients in the same way as the oauth2 package. To configure a custom client, use the oauth2 packages HTTPClient context key when constructing the context.
myClient := &http.Client{}
myCtx := context.WithValue(parentCtx, oauth2.HTTPClient, myClient)
// NewProvider will use myClient to make the request.
provider, err := oidc.NewProvider(myCtx, "https://accounts.example.com")
Index ¶
Constants ¶
const ( // ScopeOpenID is the mandatory scope for all OpenID Connect OAuth2 requests. ScopeOpenID = "openid" // ScopeOfflineAccess is an optional scope defined by OpenID Connect for requesting // OAuth2 refresh tokens. // // Support for this scope differs between OpenID Connect providers. For instance // Google rejects it, favoring appending "access_type=offline" as part of the // authorization request instead. // // See: https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess ScopeOfflineAccess = "offline_access" )
Variables ¶
var ( // ErrTokenExpired indicates that a token parsed by a verifier has expired. ErrTokenExpired = errors.New("oidc: ID Token expired") // ErrNotSupported indicates that the requested optional OpenID Connect endpoint is not supported by the provider. ErrNotSupported = errors.New("oidc: endpoint not supported") )
Functions ¶
func Nonce ¶
func Nonce(nonce string) oauth2.AuthCodeOption
Nonce returns an auth code option which requires the ID Token created by the OpenID Connect provider to contain the specified nonce.
Types ¶
type IDToken ¶
type IDToken struct {
// The URL of the server which issued this token. This will always be the same
// as the URL used for initial discovery.
Issuer string
// The client, or set of clients, that this token is issued for.
Audience []string
// A unique string which identifies the end user.
Subject string
IssuedAt time.Time
Expiry time.Time
Nonce string
// contains filtered or unexported fields
}
IDToken is an OpenID Connect extension that provides a predictable representation of an authorization event.
The ID Token only holds fields OpenID Connect requires. To access additional claims returned by the server, use the Claims method.
idToken, err := idTokenVerifier.Verify(rawIDToken)
if err != nil {
// handle error
}
var claims struct {
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
}
if err := idToken.Claims(&claims); err != nil {
// handle error
}
type IDTokenVerifier ¶
type IDTokenVerifier struct {
// contains filtered or unexported fields
}
IDTokenVerifier provides verification for ID Tokens.
type NonceSource ¶
NonceSource represents a source which can verify a nonce is valid and has not been claimed before.
type Provider ¶
type Provider struct {
Issuer string `json:"issuer"`
AuthURL string `json:"authorization_endpoint"`
TokenURL string `json:"token_endpoint"`
JWKSURL string `json:"jwks_uri"`
UserInfoURL string `json:"userinfo_endpoint"`
// contains filtered or unexported fields
}
Provider contains the subset of the OpenID Connect provider metadata needed to request and verify ID Tokens.
func NewProvider ¶
NewProvider uses the OpenID Connect disovery mechanism to construct a Provider.
func (*Provider) Endpoint ¶
Endpoint returns the OAuth2 auth and token endpoints for the given provider.
func (*Provider) NewVerifier ¶
func (p *Provider) NewVerifier(ctx context.Context, options ...VerificationOption) *IDTokenVerifier
NewVerifier returns an IDTokenVerifier that uses the provider's key set to verify JWTs.
The verifier queries the provider to update keys when a signature cannot be verified by the set of keys cached from the previous request.
type UserInfo ¶
type UserInfo struct {
Subject string `json:"sub"`
Profile string `json:"profile"`
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
// contains filtered or unexported fields
}
UserInfo represents the OpenID Connect userinfo claims.
type VerificationOption ¶
type VerificationOption interface {
// contains filtered or unexported methods
}
VerificationOption is an option provided to Provider.NewVerifier.
func VerifyAudience ¶
func VerifyAudience(clientID string) VerificationOption
VerifyAudience ensures that an ID Token was issued for the specific client.
Note that a verified token may be valid for other clients, as OpenID Connect allows a token to have multiple audiences.
func VerifyExpiry ¶
func VerifyExpiry() VerificationOption
VerifyExpiry ensures that an ID Token has not expired.
func VerifyNonce ¶
func VerifyNonce(source NonceSource) VerificationOption
VerifyNonce ensures that the ID Token contains a nonce which can be claimed by the nonce source.
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
idtoken
command
This is an example application to demonstrate parsing an ID Token.
|
This is an example application to demonstrate parsing an ID Token. |
|
nonce
command
This is an example application to demonstrate verifying an ID Token with a nonce.
|
This is an example application to demonstrate verifying an ID Token with a nonce. |
|
userinfo
command
This is an example application to demonstrate querying the user info endpoint.
|
This is an example application to demonstrate querying the user info endpoint. |