do not error if OP does not provide a redirect

This commit is contained in:
David Sharnoff 2022-10-27 18:03:19 -07:00
parent 2350b8a942
commit a689c468ff
2 changed files with 63 additions and 62 deletions

View file

@ -1,6 +1,7 @@
package client package client
import ( import (
"errors"
"net/http" "net/http"
"net/url" "net/url"
"reflect" "reflect"
@ -16,20 +17,17 @@ import (
"github.com/zitadel/oidc/pkg/oidc" "github.com/zitadel/oidc/pkg/oidc"
) )
var ( var Encoder = func() httphelper.Encoder {
Encoder = func() httphelper.Encoder {
e := schema.NewEncoder() e := schema.NewEncoder()
e.RegisterEncoder(oidc.SpaceDelimitedArray{}, func(value reflect.Value) string { e.RegisterEncoder(oidc.SpaceDelimitedArray{}, func(value reflect.Value) string {
return value.Interface().(oidc.SpaceDelimitedArray).Encode() return value.Interface().(oidc.SpaceDelimitedArray).Encode()
}) })
return e return e
}() }()
)
// Discover calls the discovery endpoint of the provided issuer and returns its configuration // Discover calls the discovery endpoint of the provided issuer and returns its configuration
// It accepts an optional argument "wellknownUrl" which can be used to overide the dicovery endpoint url // It accepts an optional argument "wellknownUrl" which can be used to overide the dicovery endpoint url
func Discover(issuer string, httpClient *http.Client, wellKnownUrl ...string) (*oidc.DiscoveryConfiguration, error) { func Discover(issuer string, httpClient *http.Client, wellKnownUrl ...string) (*oidc.DiscoveryConfiguration, error) {
wellKnown := strings.TrimSuffix(issuer, "/") + oidc.DiscoveryEndpoint wellKnown := strings.TrimSuffix(issuer, "/") + oidc.DiscoveryEndpoint
if len(wellKnownUrl) == 1 && wellKnownUrl[0] != "" { if len(wellKnownUrl) == 1 && wellKnownUrl[0] != "" {
wellKnown = wellKnownUrl[0] wellKnown = wellKnownUrl[0]
@ -80,6 +78,8 @@ type EndSessionCaller interface {
HttpClient() *http.Client HttpClient() *http.Client
} }
// CallEndSessionEndpoint terminates a session. The server may respond with
// a redirect, or it may not. If not, the returned URL will be nil.
func CallEndSessionEndpoint(request interface{}, authFn interface{}, caller EndSessionCaller) (*url.URL, error) { func CallEndSessionEndpoint(request interface{}, authFn interface{}, caller EndSessionCaller) (*url.URL, error) {
req, err := httphelper.FormRequest(caller.GetEndSessionEndpoint(), request, Encoder, authFn) req, err := httphelper.FormRequest(caller.GetEndSessionEndpoint(), request, Encoder, authFn)
if err != nil { if err != nil {
@ -91,6 +91,9 @@ func CallEndSessionEndpoint(request interface{}, authFn interface{}, caller EndS
} }
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
if errors.Is(err, http.ErrNoLocation) {
return nil, nil
}
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()

View file

@ -24,9 +24,7 @@ const (
pkceCode = "pkce" pkceCode = "pkce"
) )
var ( var ErrUserInfoSubNotMatching = errors.New("sub from userinfo does not match the sub from the id_token")
ErrUserInfoSubNotMatching = errors.New("sub from userinfo does not match the sub from the id_token")
)
// RelyingParty declares the minimal interface for oidc clients // RelyingParty declares the minimal interface for oidc clients
type RelyingParty interface { type RelyingParty interface {
@ -66,11 +64,9 @@ type RelyingParty interface {
type ErrorHandler func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string) type ErrorHandler func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string)
var ( var DefaultErrorHandler ErrorHandler = func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string) {
DefaultErrorHandler ErrorHandler = func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string) {
http.Error(w, errorType+": "+errorDesc, http.StatusInternalServerError) http.Error(w, errorType+": "+errorDesc, http.StatusInternalServerError)
} }
)
type relyingParty struct { type relyingParty struct {
issuer string issuer string
@ -579,6 +575,8 @@ func RefreshAccessToken(rp RelyingParty, refreshToken, clientAssertion, clientAs
return client.CallTokenEndpoint(request, tokenEndpointCaller{RelyingParty: rp}) return client.CallTokenEndpoint(request, tokenEndpointCaller{RelyingParty: rp})
} }
// EndSession terminates a session. The server may respond with
// a redirect, or it may not. If not, the returned URL will be nil.
func EndSession(rp RelyingParty, idToken, optionalRedirectURI, optionalState string) (*url.URL, error) { func EndSession(rp RelyingParty, idToken, optionalRedirectURI, optionalState string) (*url.URL, error) {
request := oidc.EndSessionRequest{ request := oidc.EndSessionRequest{
IdTokenHint: idToken, IdTokenHint: idToken,