Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
run: docker-compose -f docker-compose.test.yaml up -d

- name: Create kind cluster
uses: helm/kind-action@v1.1.0
uses: helm/kind-action@v1.2.0
with:
version: v0.11.1
node_image: kindest/node:v1.19.11@sha256:07db187ae84b4b7de440a73886f008cf903fcf5764ba8106a9fd5243d6f32729
Expand Down
2 changes: 1 addition & 1 deletion connector/authproxy/authproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type callback struct {
}

// LoginURL returns the URL to redirect the user to login with.
func (m *callback) LoginURL(s connector.Scopes, callbackURL, state string) (string, error) {
func (m *callback) LoginURL(s connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
u, err := url.Parse(callbackURL)
if err != nil {
return "", fmt.Errorf("failed to parse callbackURL %q: %v", callbackURL, err)
Expand Down
3 changes: 2 additions & 1 deletion connector/bitbucketcloud/bitbucketcloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"sync"
"time"

Expand Down Expand Up @@ -111,7 +112,7 @@ func (b *bitbucketConnector) oauth2Config(scopes connector.Scopes) *oauth2.Confi
}
}

func (b *bitbucketConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
func (b *bitbucketConnector) LoginURL(scopes connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
if b.redirectURI != callbackURL {
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, b.redirectURI)
}
Expand Down
3 changes: 2 additions & 1 deletion connector/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package connector
import (
"context"
"net/http"
"net/url"
)

// Connector is a mechanism for federating login to a remote identity service.
Expand Down Expand Up @@ -63,7 +64,7 @@ type CallbackConnector interface {
// requested if one has already been issues. There's no good general answer
// for these kind of restrictions, and may require this package to become more
// aware of the global set of user/connector interactions.
LoginURL(s Scopes, callbackURL, state string) (string, error)
LoginURL(s Scopes, callbackURL, state string, forwardedParams url.Values) (string, error)

// Handle the callback to the server and return an identity.
HandleCallback(s Scopes, r *http.Request) (identity Identity, err error)
Expand Down
3 changes: 2 additions & 1 deletion connector/gitea/gitea.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -82,7 +83,7 @@ func (c *giteaConnector) oauth2Config(_ connector.Scopes) *oauth2.Config {
}
}

func (c *giteaConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
func (c *giteaConnector) LoginURL(scopes connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
if c.redirectURI != callbackURL {
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", c.redirectURI, callbackURL)
}
Expand Down
3 changes: 2 additions & 1 deletion connector/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"io/ioutil"
"net"
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -187,7 +188,7 @@ func (c *githubConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config {
}
}

func (c *githubConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
func (c *githubConnector) LoginURL(scopes connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
if c.redirectURI != callbackURL {
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI)
}
Expand Down
3 changes: 2 additions & 1 deletion connector/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strconv"

"golang.org/x/oauth2"
Expand Down Expand Up @@ -98,7 +99,7 @@ func (c *gitlabConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config {
}
}

func (c *gitlabConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
func (c *gitlabConnector) LoginURL(scopes connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
if c.redirectURI != callbackURL {
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", c.redirectURI, callbackURL)
}
Expand Down
3 changes: 2 additions & 1 deletion connector/google/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"

"github.com/coreos/go-oidc/v3/oidc"
Expand Down Expand Up @@ -120,7 +121,7 @@ func (c *googleConnector) Close() error {
return nil
}

func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string) (string, error) {
func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
if c.redirectURI != callbackURL {
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI)
}
Expand Down
3 changes: 2 additions & 1 deletion connector/linkedin/linkedin.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"

"golang.org/x/oauth2"
Expand Down Expand Up @@ -62,7 +63,7 @@ var (
)

// LoginURL returns an access token request URL
func (c *linkedInConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
func (c *linkedInConnector) LoginURL(scopes connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
if c.oauth2Config.RedirectURL != callbackURL {
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q",
callbackURL, c.oauth2Config.RedirectURL)
Expand Down
3 changes: 2 additions & 1 deletion connector/microsoft/microsoft.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -151,7 +152,7 @@ func (c *microsoftConnector) oauth2Config(scopes connector.Scopes) *oauth2.Confi
}
}

func (c *microsoftConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
func (c *microsoftConnector) LoginURL(scopes connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
if c.redirectURI != callbackURL {
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI)
}
Expand Down
2 changes: 1 addition & 1 deletion connector/mock/connectortest.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type Callback struct {
}

// LoginURL returns the URL to redirect the user to login with.
func (m *Callback) LoginURL(s connector.Scopes, callbackURL, state string) (string, error) {
func (m *Callback) LoginURL(s connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
u, err := url.Parse(callbackURL)
if err != nil {
return "", fmt.Errorf("failed to parse callbackURL %q: %v", callbackURL, err)
Expand Down
86 changes: 54 additions & 32 deletions connector/oidc/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ type Config struct {
// InsecureEnableGroups enables groups claims. This is disabled by default until https://github.com/dexidp/dex/issues/1065 is resolved
InsecureEnableGroups bool `json:"insecureEnableGroups"`

// Skips checking whether the requested domain in the Login Callback matches the configured Issuer
InsecureSkipIssuerCallbackDomainCheck bool `json:"insecureSkipIssuerCallbackDomainCheck"`

// GetUserInfo uses the userinfo endpoint to get additional claims for
// the token. This is especially useful where upstreams return "thin"
// id tokens
Expand All @@ -56,6 +59,8 @@ type Config struct {
// PromptType will be used fot the prompt parameter (when offline_access, by default prompt=consent)
PromptType string `json:"promptType"`

ForwardedLoginParams []string `json:"forwardedLoginParams"`

ClaimMapping struct {
// Configurable key which contains the preferred username claims
PreferredUsernameKey string `json:"preferred_username"` // defaults to "preferred_username"
Expand Down Expand Up @@ -125,6 +130,8 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
scopes = append(scopes, "profile", "email")
}

scopes = append(scopes, "offline_access")

// PromptType should be "consent" by default, if not set
if c.PromptType == "" {
c.PromptType = "consent"
Expand All @@ -144,18 +151,20 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
verifier: provider.Verifier(
&oidc.Config{ClientID: clientID},
),
logger: logger,
cancel: cancel,
hostedDomains: c.HostedDomains,
insecureSkipEmailVerified: c.InsecureSkipEmailVerified,
insecureEnableGroups: c.InsecureEnableGroups,
getUserInfo: c.GetUserInfo,
promptType: c.PromptType,
userIDKey: c.UserIDKey,
userNameKey: c.UserNameKey,
preferredUsernameKey: c.ClaimMapping.PreferredUsernameKey,
emailKey: c.ClaimMapping.EmailKey,
groupsKey: c.ClaimMapping.GroupsKey,
logger: logger,
cancel: cancel,
hostedDomains: c.HostedDomains,
insecureSkipEmailVerified: c.InsecureSkipEmailVerified,
insecureEnableGroups: c.InsecureEnableGroups,
insecureSkipIssuerCallbackDomainCheck: c.InsecureSkipIssuerCallbackDomainCheck,
getUserInfo: c.GetUserInfo,
promptType: c.PromptType,
userIDKey: c.UserIDKey,
userNameKey: c.UserNameKey,
preferredUsernameKey: c.ClaimMapping.PreferredUsernameKey,
emailKey: c.ClaimMapping.EmailKey,
groupsKey: c.ClaimMapping.GroupsKey,
forwardedLoginParams: c.ForwardedLoginParams,
}, nil
}

Expand All @@ -165,31 +174,33 @@ var (
)

type oidcConnector struct {
provider *oidc.Provider
redirectURI string
oauth2Config *oauth2.Config
verifier *oidc.IDTokenVerifier
cancel context.CancelFunc
logger log.Logger
hostedDomains []string
insecureSkipEmailVerified bool
insecureEnableGroups bool
getUserInfo bool
promptType string
userIDKey string
userNameKey string
preferredUsernameKey string
emailKey string
groupsKey string
provider *oidc.Provider
redirectURI string
oauth2Config *oauth2.Config
verifier *oidc.IDTokenVerifier
cancel context.CancelFunc
logger log.Logger
hostedDomains []string
insecureSkipEmailVerified bool
insecureEnableGroups bool
insecureSkipIssuerCallbackDomainCheck bool
getUserInfo bool
promptType string
userIDKey string
userNameKey string
preferredUsernameKey string
emailKey string
groupsKey string
forwardedLoginParams []string
}

func (c *oidcConnector) Close() error {
c.cancel()
return nil
}

func (c *oidcConnector) LoginURL(s connector.Scopes, callbackURL, state string) (string, error) {
if c.redirectURI != callbackURL {
func (c *oidcConnector) LoginURL(s connector.Scopes, callbackURL, state string, forwardParams url.Values) (string, error) {
if c.redirectURI != callbackURL && !c.insecureSkipIssuerCallbackDomainCheck {
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI)
}

Expand All @@ -202,8 +213,19 @@ func (c *oidcConnector) LoginURL(s connector.Scopes, callbackURL, state string)
opts = append(opts, oauth2.SetAuthURLParam("hd", preferredDomain))
}

if s.OfflineAccess {
opts = append(opts, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", c.promptType))
for p := range forwardParams {
paramApproved := false
for _, approvedParam := range c.forwardedLoginParams {
if p == approvedParam {
paramApproved = true
break
}
}
if paramApproved {
opts = append(opts, oauth2.SetAuthURLParam(p, forwardParams.Get(p)))
} else {
c.logger.Infof("oidc: auth query parameter %s, is unapproved and was not forwarded to the connector idp", p)
}
}
return c.oauth2Config.AuthCodeURL(state, opts...), nil
}
Expand Down
3 changes: 2 additions & 1 deletion connector/openshift/openshift.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"io/ioutil"
"net"
"net/http"
"net/url"
"strings"
"time"

Expand Down Expand Up @@ -117,7 +118,7 @@ func (c *openshiftConnector) Close() error {
}

// LoginURL returns the URL to redirect the user to login with.
func (c *openshiftConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
func (c *openshiftConnector) LoginURL(scopes connector.Scopes, callbackURL, state string, _ url.Values) (string, error) {
if c.redirectURI != callbackURL {
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI)
}
Expand Down
22 changes: 11 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/dexidp/dex
go 1.16

require (
entgo.io/ent v0.8.0
entgo.io/ent v0.11.1
github.com/AppsFlyer/go-sundheit v0.4.0
github.com/Masterminds/sprig/v3 v3.2.2
github.com/beevik/etree v1.1.0
Expand All @@ -17,24 +17,24 @@ require (
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/kylelemons/godebug v1.1.0
github.com/lib/pq v1.10.2
github.com/lib/pq v1.10.5
github.com/mattermost/xml-roundtrip-validator v0.1.0
github.com/mattn/go-sqlite3 v1.14.7
github.com/mattn/go-sqlite3 v1.14.13
github.com/oklog/run v1.1.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.0
github.com/russellhaering/goxmldsig v1.1.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.1.3
github.com/stretchr/testify v1.7.0
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.5.0
github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942
go.etcd.io/etcd/client/pkg/v3 v3.5.0
go.etcd.io/etcd/client/v3 v3.5.0
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420
golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1
google.golang.org/api v0.49.0
google.golang.org/grpc v1.38.0
google.golang.org/protobuf v1.27.1
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
google.golang.org/api v0.87.0
google.golang.org/grpc v1.48.0
google.golang.org/protobuf v1.28.0
gopkg.in/square/go-jose.v2 v2.6.0
)

Expand Down
Loading