Skip to content

Commit a16edf6

Browse files
committed
#454: Add support for Hashicorp Vault through discovery
1 parent 60d436e commit a16edf6

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
/bin
22
/gopath
3+
4+
.idea/

oidc/oidc.go

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ var supportedAlgorithms = map[string]bool{
162162
// parsing.
163163
//
164164
// // Directly fetch the metadata document.
165-
// resp, err := http.Get("https://login.example.com/custom-metadata-path")
165+
// resp, err := http.Get("https://login.example.com/custom-metadata-path")
166166
// if err != nil {
167167
// // ...
168168
// }
@@ -236,7 +236,19 @@ func (p *ProviderConfig) NewProvider(ctx context.Context) *Provider {
236236
//
237237
// See: https://openid.net/specs/openid-connect-discovery-1_0.html
238238
func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
239-
wellKnown := strings.TrimSuffix(issuer, "/") + "/.well-known/openid-configuration"
239+
return NewProviderWithBaseUrl(ctx, "", issuer)
240+
}
241+
242+
// NewProviderWithBaseUrl uses the OpenID Connect discovery mechanism to construct a Provider.
243+
//
244+
// An identity provider may report its issuer as a path rather than a full URL. This is not spec
245+
// conformant, but for example the case with Hashicorp Vault (e.g. /v1/identity/oidc/provider/default)
246+
//
247+
// With this constructor, discovery can still be used with a combination of baseUrl and issuer.
248+
//
249+
// See: https://openid.net/specs/openid-connect-discovery-1_0.html
250+
func NewProviderWithBaseUrl(ctx context.Context, baseUrl, issuer string) (*Provider, error) {
251+
wellKnown := baseUrl + strings.TrimSuffix(issuer, "/") + "/.well-known/openid-configuration"
240252
req, err := http.NewRequest("GET", wellKnown, nil)
241253
if err != nil {
242254
return nil, err
@@ -262,11 +274,11 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
262274
return nil, fmt.Errorf("oidc: failed to decode provider discovery object: %v", err)
263275
}
264276

265-
issuerURL, skipIssuerValidation := ctx.Value(issuerURLKey).(string)
277+
issuerUrl, skipIssuerValidation := ctx.Value(issuerURLKey).(string)
266278
if !skipIssuerValidation {
267-
issuerURL = issuer
279+
issuerUrl = issuer
268280
}
269-
if p.Issuer != issuerURL && !skipIssuerValidation {
281+
if p.Issuer != issuerUrl && !skipIssuerValidation {
270282
return nil, fmt.Errorf("oidc: issuer did not match the issuer returned by provider, expected %q got %q", issuer, p.Issuer)
271283
}
272284
var algs []string
@@ -275,20 +287,28 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
275287
algs = append(algs, a)
276288
}
277289
}
290+
291+
withBaseUrl := func(val string) string {
292+
if val != "" && !strings.HasPrefix(val, "http") {
293+
val = baseUrl + val
294+
}
295+
return val
296+
}
297+
278298
return &Provider{
279-
issuer: issuerURL,
280-
authURL: p.AuthURL,
281-
tokenURL: p.TokenURL,
282-
deviceAuthURL: p.DeviceAuthURL,
283-
userInfoURL: p.UserInfoURL,
284-
jwksURL: p.JWKSURL,
299+
issuer: issuerUrl,
300+
authURL: withBaseUrl(p.AuthURL),
301+
tokenURL: withBaseUrl(p.TokenURL),
302+
deviceAuthURL: withBaseUrl(p.DeviceAuthURL),
303+
userInfoURL: withBaseUrl(p.UserInfoURL),
304+
jwksURL: withBaseUrl(p.JWKSURL),
285305
algorithms: algs,
286306
rawClaims: body,
287307
client: getClient(ctx),
288308
}, nil
289309
}
290310

291-
// Claims unmarshals raw fields returned by the server during discovery.
311+
// Claims unmarshalls raw fields returned by the server during discovery.
292312
//
293313
// var claims struct {
294314
// ScopesSupported []string `json:"scopes_supported"`

0 commit comments

Comments
 (0)