From 5ae3bb7869ff5f4ee34cf2ca6f144e6ab4e32b7d Mon Sep 17 00:00:00 2001 From: Thom Seddon Date: Thu, 11 Jun 2020 12:24:51 +0100 Subject: [PATCH] Add support for resource indicator to OIDC provider (#131) --- README.md | 1 + internal/provider/oidc.go | 4 ++-- internal/provider/oidc_test.go | 27 +++++++++++++++++++++++++++ internal/provider/providers.go | 7 +++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e03ee155..ad7e24fd 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ OIDC Provider: --providers.oidc.issuer-url= Issuer URL [$PROVIDERS_OIDC_ISSUER_URL] --providers.oidc.client-id= Client ID [$PROVIDERS_OIDC_CLIENT_ID] --providers.oidc.client-secret= Client Secret [$PROVIDERS_OIDC_CLIENT_SECRET] + --providers.oidc.resource= Optional resource indicator [$PROVIDERS_OIDC_RESOURCE] Help Options: -h, --help Show this help message diff --git a/internal/provider/oidc.go b/internal/provider/oidc.go index 0ba76606..ac6f60e4 100644 --- a/internal/provider/oidc.go +++ b/internal/provider/oidc.go @@ -10,12 +10,12 @@ import ( // OIDC provider type OIDC struct { - OAuthProvider - IssuerURL string `long:"issuer-url" env:"ISSUER_URL" description:"Issuer URL"` ClientID string `long:"client-id" env:"CLIENT_ID" description:"Client ID"` ClientSecret string `long:"client-secret" env:"CLIENT_SECRET" description:"Client Secret" json:"-"` + OAuthProvider + provider *oidc.Provider verifier *oidc.IDTokenVerifier } diff --git a/internal/provider/oidc_test.go b/internal/provider/oidc_test.go index 225d05d0..a2513338 100644 --- a/internal/provider/oidc_test.go +++ b/internal/provider/oidc_test.go @@ -59,6 +59,33 @@ func TestOIDCGetLoginURL(t *testing.T) { // Calling the method should not modify the underlying config assert.Equal("", provider.Config.RedirectURL) + + // + // Test with resource config option + // + provider.Resource = "resourcetest" + + // Check url + uri, err = url.Parse(provider.GetLoginURL("http://example.com/_oauth", "state")) + assert.Nil(err) + assert.Equal(serverURL.Scheme, uri.Scheme) + assert.Equal(serverURL.Host, uri.Host) + assert.Equal("/auth", uri.Path) + + // Check query string + qs = uri.Query() + expectedQs = url.Values{ + "client_id": []string{"idtest"}, + "redirect_uri": []string{"http://example.com/_oauth"}, + "response_type": []string{"code"}, + "scope": []string{"openid profile email"}, + "state": []string{"state"}, + "resource": []string{"resourcetest"}, + } + assert.Equal(expectedQs, qs) + + // Calling the method should not modify the underlying config + assert.Equal("", provider.Config.RedirectURL) } func TestOIDCExchangeCode(t *testing.T) { diff --git a/internal/provider/providers.go b/internal/provider/providers.go index b81357fe..7fd0510e 100644 --- a/internal/provider/providers.go +++ b/internal/provider/providers.go @@ -36,6 +36,8 @@ type User struct { // OAuthProvider is a provider using the oauth2 library type OAuthProvider struct { + Resource string `long:"resource" env:"RESOURCE" description:"Optional resource indicator"` + Config *oauth2.Config ctx context.Context } @@ -51,6 +53,11 @@ func (p *OAuthProvider) ConfigCopy(redirectURI string) oauth2.Config { // OAuthGetLoginURL provides a base "GetLoginURL" for proiders using OAauth2 func (p *OAuthProvider) OAuthGetLoginURL(redirectURI, state string) string { config := p.ConfigCopy(redirectURI) + + if p.Resource != "" { + return config.AuthCodeURL(state, oauth2.SetAuthURLParam("resource", p.Resource)) + } + return config.AuthCodeURL(state) }