use our oidc client

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
Jörn Friedrich Dreyer
2023-04-19 17:32:25 +02:00
committed by Christian Richter
parent 014308ddc9
commit 58dce9bed8
5 changed files with 75 additions and 98 deletions
+51 -45
View File
@@ -9,6 +9,7 @@ import (
"mime"
"net/http"
"strings"
"sync"
gOidc "github.com/coreos/go-oidc/v3/oidc"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
@@ -37,7 +38,8 @@ type KeySet interface {
type oidcClient struct {
issuer string
provider ProviderMetadata
provider *ProviderMetadata
providerLock *sync.Mutex
skipIssuerValidation bool
remoteKeySet KeySet
algorithms []string
@@ -67,52 +69,56 @@ func NewOIDCClient(opts ...Option) OIDCProvider {
options := newOptions(opts...)
return &oidcClient{
Logger: options.Logger,
issuer: options.OidcIssuer,
Logger: options.Logger,
issuer: options.OidcIssuer,
client: options.HTTPClient,
providerLock: &sync.Mutex{},
}
}
func (c *oidcClient) lookupWellKnownOpenidConfiguration(ctx context.Context) error {
wellKnown := strings.TrimSuffix(c.issuer, "/") + "/.well-known/openid-configuration"
req, err := http.NewRequest("GET", wellKnown, nil)
if err != nil {
return err
}
resp, err := c.client.Do(req.WithContext(ctx))
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("unable to read response body: %v", err)
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("%s: %s", resp.Status, body)
}
var p ProviderMetadata
err = unmarshalResp(resp, body, &p)
if err != nil {
return fmt.Errorf("oidc: failed to decode provider discovery object: %v", err)
}
if !c.skipIssuerValidation && p.Issuer != c.issuer {
return fmt.Errorf("oidc: issuer did not match the issuer returned by provider, expected %q got %q", c.issuer, p.Issuer)
}
var algs []string
for _, a := range p.IDTokenSigningAlgValuesSupported {
if supportedAlgorithms[a] {
algs = append(algs, a)
c.providerLock.Lock()
defer c.providerLock.Unlock()
if c.provider == nil {
wellKnown := strings.TrimSuffix(c.issuer, "/") + "/.well-known/openid-configuration"
req, err := http.NewRequest("GET", wellKnown, nil)
if err != nil {
return err
}
}
c.provider = p
c.algorithms = algs
c.remoteKeySet = gOidc.NewRemoteKeySet(ctx, p.JwksURI)
resp, err := c.client.Do(req.WithContext(ctx))
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("unable to read response body: %v", err)
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("%s: %s", resp.Status, body)
}
var p ProviderMetadata
err = unmarshalResp(resp, body, &p)
if err != nil {
return fmt.Errorf("oidc: failed to decode provider discovery object: %v", err)
}
if !c.skipIssuerValidation && p.Issuer != c.issuer {
return fmt.Errorf("oidc: issuer did not match the issuer returned by provider, expected %q got %q", c.issuer, p.Issuer)
}
var algs []string
for _, a := range p.IDTokenSigningAlgValuesSupported {
if supportedAlgorithms[a] {
algs = append(algs, a)
}
}
c.provider = &p
c.algorithms = algs
c.remoteKeySet = gOidc.NewRemoteKeySet(ctx, p.JwksURI)
}
return nil
}
@@ -159,11 +165,11 @@ func (u *UserInfo) Claims(v interface{}) error {
}
func (c *oidcClient) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource) (*UserInfo, error) {
if err := c.lookupWellKnownOpenidConfiguration(ctx); err != nil {
return nil, err
}
if c.provider.UserinfoEndpoint == "" {
// try lazy initialization TODO use sync.once
if err := c.lookupWellKnownOpenidConfiguration(ctx); err != nil {
return nil, err
}
if c.provider.UserinfoEndpoint == "" {
return nil, errors.New("oidc: user info endpoint is not supported by this provider")
}
+10
View File
@@ -1,6 +1,8 @@
package oidc
import (
"net/http"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
)
@@ -9,6 +11,8 @@ type Option func(o *Options)
// Options defines the available options for this package.
type Options struct {
// HTTPClient to use for requests
HTTPClient *http.Client
// Logger to use for logging, must be set
Logger log.Logger
// The OpenID Connect Issuer URL
@@ -39,3 +43,9 @@ func WithLogger(val log.Logger) Option {
o.Logger = val
}
}
func WithHTTPClient(val *http.Client) Option {
return func(o *Options) {
o.HTTPClient = val
}
}