Documentation ¶
Overview ¶
callback is a package that provides callbacks (in the form of http.HandlerFunc) for handling OIDC provider responses to authorization code flow (with optional PKCE) and implicit flow authentication attempts.
Example ¶
// Create a new Config pc, err := oidc.NewConfig( "http://your-issuer.com/", "your_client_id", "your_client_secret", []oidc.Alg{oidc.RS256}, []string{"http://your_redirect_url/auth-code-callback", "http://your_redirect_url/implicit-callback"}, ) if err != nil { // handle error } // Create a provider p, err := oidc.NewProvider(pc) if err != nil { // handle error } defer p.Done() // Create a Request for a user's authentication attempt that will use the // authorization code flow. (See NewRequest(...) using the WithPKCE and // WithImplicit options for creating a Request that uses those flows.) ttl := 2 * time.Minute authCodeAttempt, err := oidc.NewRequest(ttl, "http://your_redirect_url/auth-code-callback") if err != nil { // handle error } // Create a Request for a user's authentication attempt using an implicit // flow. implicitAttempt, err := oidc.NewRequest(ttl, "http://your_redirect_url/implicit-callback") if err != nil { // handle error } // Create an authorization code flow callback // A function to handle successful attempts. successFn := func( state string, t oidc.Token, w http.ResponseWriter, req *http.Request, ) { w.WriteHeader(http.StatusOK) printableToken := fmt.Sprintf("id_token: %s", string(t.IDToken())) _, _ = w.Write([]byte(printableToken)) } // A function to handle errors and failed attempts. errorFn := func( state string, r *AuthenErrorResponse, e error, w http.ResponseWriter, req *http.Request, ) { if e != nil { w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte(e.Error())) return } w.WriteHeader(http.StatusUnauthorized) } // create the authorization code callback and register it for use. authCodeCallback, err := AuthCode(context.Background(), p, &SingleRequestReader{Request: authCodeAttempt}, successFn, errorFn) if err != nil { // handle error } http.HandleFunc("/auth-code-callback", authCodeCallback) // create an implicit flow callback and register it for use. implicitCallback, err := Implicit(context.Background(), p, &SingleRequestReader{Request: implicitAttempt}, successFn, errorFn) if err != nil { // handle error } http.HandleFunc("/implicit-callback", implicitCallback)
Output:
Index ¶
- func AuthCode(ctx context.Context, p *oidc.Provider, rw RequestReader, ...) (http.HandlerFunc, error)
- func Implicit(ctx context.Context, p *oidc.Provider, rw RequestReader, ...) (http.HandlerFunc, error)
- type AuthenErrorResponse
- type ErrorResponseFunc
- type RequestReader
- type SingleRequestReader
- type SuccessResponseFunc
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AuthCode ¶
func AuthCode(ctx context.Context, p *oidc.Provider, rw RequestReader, sFn SuccessResponseFunc, eFn ErrorResponseFunc) (http.HandlerFunc, error)
AuthCode creates an oidc authorization code callback handler which uses a RequestReader to read existing oidc.Request(s) via the request's oidc "state" parameter as a key for the lookup. In additional to the typical authorization code flow, it also handles the authorization code flow with PKCE.
The SuccessResponseFunc is used to create a response when callback is successful.
The ErrorResponseFunc is to create a response when the callback fails.
Example ¶
// Create a new Config pc, err := oidc.NewConfig( "http://your-issuer.com/", "your_client_id", "your_client_secret", []oidc.Alg{oidc.RS256}, []string{"http://your_redirect_url/auth-code-callback"}, ) if err != nil { // handle error } // Create a provider p, err := oidc.NewProvider(pc) if err != nil { // handle error } defer p.Done() // Create a Request for a user's authentication attempt that will use the // authorization code flow. (See NewRequest(...) using the WithPKCE and // WithImplicit options for creating a Request that uses those flows.) ttl := 2 * time.Minute authCodeAttempt, err := oidc.NewRequest(ttl, "http://your_redirect_url/auth-code-callback") if err != nil { // handle error } // Create an authorization code flow callback // A function to handle successful attempts. successFn := func( state string, t oidc.Token, w http.ResponseWriter, req *http.Request, ) { w.WriteHeader(http.StatusOK) printableToken := fmt.Sprintf("id_token: %s", string(t.IDToken())) _, _ = w.Write([]byte(printableToken)) } // A function to handle errors and failed attempts. errorFn := func( state string, r *AuthenErrorResponse, e error, w http.ResponseWriter, req *http.Request, ) { if e != nil { w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte(e.Error())) return } w.WriteHeader(http.StatusUnauthorized) } // create the authorization code callback and register it for use. authCodeCallback, err := AuthCode(context.Background(), p, &SingleRequestReader{Request: authCodeAttempt}, successFn, errorFn) if err != nil { // handle error } http.HandleFunc("/auth-code-callback", authCodeCallback)
Output:
func Implicit ¶
func Implicit(ctx context.Context, p *oidc.Provider, rw RequestReader, sFn SuccessResponseFunc, eFn ErrorResponseFunc) (http.HandlerFunc, error)
Implicit creates an oidc implicit flow callback handler which uses a RequestReader to read existing oidc.Request(s) via the request's oidc "state" parameter as a key for the lookup.
It should be noted that if your OIDC provider supports PKCE, then use it over the implicit flow
The SuccessResponseFunc is used to create a response when callback is successful.
The ErrorResponseFunc is to create a response when the callback fails.
Example ¶
// Create a new Config pc, err := oidc.NewConfig( "http://your-issuer.com/", "your_client_id", "your_client_secret", []oidc.Alg{oidc.RS256}, []string{"http://your_redirect_url/implicit-callback"}, ) if err != nil { // handle error } // Create a provider p, err := oidc.NewProvider(pc) if err != nil { // handle error } defer p.Done() // Create a Request for a user's authentication attempt using an implicit // flow. ttl := 2 * time.Minute implicitAttempt, err := oidc.NewRequest(ttl, "http://your_redirect_url/implicit-callback") if err != nil { // handle error } // Create an authorization code flow callback // A function to handle successful attempts. successFn := func( state string, t oidc.Token, w http.ResponseWriter, req *http.Request, ) { w.WriteHeader(http.StatusOK) printableToken := fmt.Sprintf("id_token: %s", string(t.IDToken())) _, _ = w.Write([]byte(printableToken)) } // A function to handle errors and failed attempts. errorFn := func( state string, r *AuthenErrorResponse, e error, w http.ResponseWriter, req *http.Request, ) { if e != nil { w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte(e.Error())) return } w.WriteHeader(http.StatusUnauthorized) } // create an implicit flow callback and register it for use. implicitCallback, err := Implicit(context.Background(), p, &SingleRequestReader{Request: implicitAttempt}, successFn, errorFn) if err != nil { // handle error } http.HandleFunc("/implicit-callback", implicitCallback)
Output:
Types ¶
type AuthenErrorResponse ¶
AuthenErrorResponse represents Oauth2 error responses. See: https://openid.net/specs/openid-connect-core-1_0.html#AuthError
type ErrorResponseFunc ¶
type ErrorResponseFunc func(state string, respErr *AuthenErrorResponse, e error, w http.ResponseWriter, req *http.Request)
ErrorResponseFunc is used by Callbacks to create a http response when the callback fails.
The function receives the state returned as part of the oidc authentication response. It also gets parameters for the oidc authentication error response and/or the callback error raised while processing the request. The function should use the http.ResponseWriter to send back whatever content (headers, html, JSON, etc) it wishes to the client that originated the oidc flow.
Just a reminder that the function parameters could also be used to update the oidc.Request for the request or log info about the request, if the implementation requires it.
type RequestReader ¶
type RequestReader interface { // Read an existing Request entry. The returned request's State() // must match the state used to look it up. Implementations must be // concurrently safe, which likely means returning a deep copy. Read(ctx context.Context, state string) (oidc.Request, error) }
RequestReader defines an interface for finding and reading an oidc.Request
Implementations must be concurrently safe, since the reader will likely be used within a concurrent http.Handler
type SingleRequestReader ¶
SingleRequestReader implements the RequestReader interface for a single request. It is concurrently safe.
type SuccessResponseFunc ¶
SuccessResponseFunc is used by Callbacks to create a http response when the callback is successful.
The function state parameter will contain the state that was returned as part of a successful oidc authentication response. The oidc.Token is the result of a successful token exchange with the provider. The function should use the http.ResponseWriter to send back whatever content (headers, html, JSON, etc) it wishes to the client that originated the oidc flow.
Just a reminder that the function parameters could also be used to update the oidc.Request for the request or log info about the request, if the implementation requires it.