Esempio n. 1
0
func (r *httpProviderConfigGetter) Get() (cfg ProviderConfig, err error) {
	req, err := http.NewRequest("GET", r.issuerURL+discoveryConfigPath, nil)
	if err != nil {
		return
	}

	resp, err := r.hc.Do(req)
	if err != nil {
		return
	}
	defer resp.Body.Close()

	if err = json.NewDecoder(resp.Body).Decode(&cfg); err != nil {
		return
	}

	var ttl time.Duration
	var ok bool
	ttl, ok, err = phttp.Cacheable(resp.Header)
	if err != nil {
		return
	} else if ok {
		cfg.ExpiresAt = r.clock.Now().UTC().Add(ttl)
	}

	// The issuer value returned MUST be identical to the Issuer URL that was directly used to retrieve the configuration information.
	// http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation
	if !urlEqual(cfg.Issuer, r.issuerURL) {
		err = fmt.Errorf(`"issuer" in config (%v) does not match provided issuer URL (%v)`, cfg.Issuer, r.issuerURL)
		return
	}

	return
}
Esempio n. 2
0
func (r *remotePublicKeyRepo) Get() (key.KeySet, error) {
	req, err := http.NewRequest("GET", r.ep, nil)
	if err != nil {
		return nil, err
	}

	resp, err := r.hc.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var d struct {
		Keys []jose.JWK `json:"keys"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
		return nil, err
	}

	if len(d.Keys) == 0 {
		return nil, errors.New("zero keys in response")
	}

	ttl, ok, err := phttp.Cacheable(resp.Header)
	if err != nil {
		return nil, err
	}
	if !ok {
		return nil, errors.New("HTTP cache headers not set")
	}

	exp := time.Now().UTC().Add(ttl)
	ks := key.NewPublicKeySet(d.Keys, exp)
	return ks, nil
}
Esempio n. 3
0
func (tkr *Tracker) updateJWKSet(client *http.Client) error {
	glog.Info("Attemping to update JWK Set")
	resp, err := client.Get(tkr.Config.JWKSetURI)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	var jwks jwkSet
	err = json.NewDecoder(resp.Body).Decode(&jwks)
	if err != nil {
		return err
	}

	if len(jwks.Keys) == 0 {
		return errors.New("Failed to find any keys from JWK Set URI")
	}

	if jwks.Issuer == "" {
		return errors.New("Failed to find any issuer from JWK Set URI")
	}

	ttl, _, _ := oidchttp.Cacheable(resp.Header)
	if ttl == 0 {
		ttl = jwkTTLFallback
	}
	jwks.validUntil = time.Now().Add(ttl)

	tkr.jwkSet = jwks
	glog.Info("Successfully updated JWK Set")
	return nil
}
Esempio n. 4
0
func (op *OIDCProvider) FetchCustomProviderConfig(discoveryURL string) (*oidc.ProviderConfig, error) {

	var customConfig OidcProviderConfiguration

	// If discovery URL is empty, use the standard discovery URL
	if discoveryURL == "" {
		discoveryURL = strings.TrimSuffix(op.Issuer, "/") + discoveryConfigPath
	}

	base.LogTo("OIDC+", "Fetching custom provider config from %s", discoveryURL)
	req, err := http.NewRequest("GET", discoveryURL, nil)
	if err != nil {
		base.LogTo("OIDC+", "Error building new request for URL %s: %v", discoveryURL, err)
		return nil, err
	}
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		base.LogTo("OIDC+", "Error invoking calling discovery URL %s: %v", discoveryURL, err)
		return nil, err
	}
	defer resp.Body.Close()
	if err := json.NewDecoder(resp.Body).Decode(&customConfig); err != nil {
		base.LogTo("OIDC+", "Error parsing body %s: %v", discoveryURL, err)
		return nil, err
	}

	var oidcConfig oidc.ProviderConfig
	oidcConfig, err = customConfig.AsProviderConfig()
	if err != nil {
		base.LogTo("OIDC+", "Error invoking calling discovery URL %s: %v", discoveryURL, err)
		return nil, err
	}

	// Set expiry on config, if defined in response header
	var ttl time.Duration
	var ok bool
	ttl, ok, err = phttp.Cacheable(resp.Header)
	if err != nil {
		return nil, err
	} else if ok {
		oidcConfig.ExpiresAt = time.Now().UTC().Add(ttl)
	}

	base.LogTo("OIDC+", "Returning config: %v", oidcConfig)
	return &oidcConfig, nil

}
Esempio n. 5
0
func (r *httpProviderConfigGetter) Get() (cfg ProviderConfig, err error) {
	// If the Issuer value contains a path component, any terminating / MUST be removed before
	// appending /.well-known/openid-configuration.
	// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest
	discoveryURL := strings.TrimSuffix(r.issuerURL, "/") + discoveryConfigPath
	req, err := http.NewRequest("GET", discoveryURL, nil)
	if err != nil {
		return
	}

	resp, err := r.hc.Do(req)
	if err != nil {
		return
	}
	defer resp.Body.Close()

	if err = json.NewDecoder(resp.Body).Decode(&cfg); err != nil {
		return
	}

	var ttl time.Duration
	var ok bool
	ttl, ok, err = phttp.Cacheable(resp.Header)
	if err != nil {
		return
	} else if ok {
		cfg.ExpiresAt = r.clock.Now().UTC().Add(ttl)
	}

	// The issuer value returned MUST be identical to the Issuer URL that was directly used to retrieve the configuration information.
	// http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation
	if !urlEqual(cfg.Issuer.String(), r.issuerURL) {
		err = fmt.Errorf(`"issuer" in config (%v) does not match provided issuer URL (%v)`, cfg.Issuer, r.issuerURL)
		return
	}

	return
}