This repository has been archived on 2023-08-14. You can view files and clone it, but cannot push or open issues or pull requests.
dex/vendor/github.com/ericchiang/oidc
2016-07-26 15:51:24 -07:00
..
examples initial commit 2016-07-26 15:51:24 -07:00
internal initial commit 2016-07-26 15:51:24 -07:00
oidcproxy initial commit 2016-07-26 15:51:24 -07:00
testdata initial commit 2016-07-26 15:51:24 -07:00
doc.go initial commit 2016-07-26 15:51:24 -07:00
jwks_test.go initial commit 2016-07-26 15:51:24 -07:00
jwks.go initial commit 2016-07-26 15:51:24 -07:00
LICENSE initial commit 2016-07-26 15:51:24 -07:00
nonce.go initial commit 2016-07-26 15:51:24 -07:00
oidc_test.go initial commit 2016-07-26 15:51:24 -07:00
oidc.go initial commit 2016-07-26 15:51:24 -07:00
README.md initial commit 2016-07-26 15:51:24 -07:00

OpenID Connect client support for Go

GoDoc

This package 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
	}

	// ...
})

Or the provider can be used to verify and inspect the OpenID Connect ID Token in the token response.

verifier := provider.NewVerifier(ctx)

The returned verifier can be used to ensure the ID Token (a JWT) is signed by the provider.

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.
	payload, 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 idToken struct {
		Email         string `json:"email"`
		EmailVerified bool   `json:"email_verified"`
	}
	if err := json.Unmarshal(payload, &idToken); err != nil {
		http.Error(w, "Failed to unmarshal ID Token: "+err.Error(), http.StatusInternalServerError)
		return
	}

	// ...
})