OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
Eric Chiang cab271f304 initial commit 10 years ago
..
examples initial commit 10 years ago
internal initial commit 10 years ago
oidcproxy initial commit 10 years ago
testdata initial commit 10 years ago
LICENSE initial commit 10 years ago
README.md initial commit 10 years ago
doc.go initial commit 10 years ago
jwks.go initial commit 10 years ago
jwks_test.go initial commit 10 years ago
nonce.go initial commit 10 years ago
oidc.go initial commit 10 years ago
oidc_test.go initial commit 10 years ago

README.md

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
	}

	// ...
})