|
|
|
@ -13,6 +13,7 @@ import ( |
|
|
|
"golang.org/x/net/context" |
|
|
|
"golang.org/x/net/context" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/Sirupsen/logrus" |
|
|
|
"github.com/Sirupsen/logrus" |
|
|
|
|
|
|
|
"github.com/gorilla/handlers" |
|
|
|
"github.com/gorilla/mux" |
|
|
|
"github.com/gorilla/mux" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/coreos/dex/connector" |
|
|
|
"github.com/coreos/dex/connector" |
|
|
|
@ -42,10 +43,10 @@ type Config struct { |
|
|
|
// flow. If no response types are supplied this value defaults to "code".
|
|
|
|
// flow. If no response types are supplied this value defaults to "code".
|
|
|
|
SupportedResponseTypes []string |
|
|
|
SupportedResponseTypes []string |
|
|
|
|
|
|
|
|
|
|
|
// List of allowed origins for CORS requests on discovery endpoint.
|
|
|
|
// List of allowed origins for CORS requests on discovery, token and keys endpoint.
|
|
|
|
// If none are indicated, CORS requests are disabled. Passing in "*" will allow any
|
|
|
|
// If none are indicated, CORS requests are disabled. Passing in "*" will allow any
|
|
|
|
// domain.
|
|
|
|
// domain.
|
|
|
|
DiscoveryAllowedOrigins []string |
|
|
|
AllowedOrigins []string |
|
|
|
|
|
|
|
|
|
|
|
// If enabled, the server won't prompt the user to approve authorization requests.
|
|
|
|
// If enabled, the server won't prompt the user to approve authorization requests.
|
|
|
|
// Logging in implies approval.
|
|
|
|
// Logging in implies approval.
|
|
|
|
@ -116,8 +117,6 @@ type Server struct { |
|
|
|
|
|
|
|
|
|
|
|
supportedResponseTypes map[string]bool |
|
|
|
supportedResponseTypes map[string]bool |
|
|
|
|
|
|
|
|
|
|
|
discoveryAllowedOrigins []string |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
now func() time.Time |
|
|
|
now func() time.Time |
|
|
|
|
|
|
|
|
|
|
|
idTokensValidFor time.Duration |
|
|
|
idTokensValidFor time.Duration |
|
|
|
@ -185,16 +184,15 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
s := &Server{ |
|
|
|
s := &Server{ |
|
|
|
issuerURL: *issuerURL, |
|
|
|
issuerURL: *issuerURL, |
|
|
|
connectors: make(map[string]Connector), |
|
|
|
connectors: make(map[string]Connector), |
|
|
|
storage: newKeyCacher(c.Storage, now), |
|
|
|
storage: newKeyCacher(c.Storage, now), |
|
|
|
supportedResponseTypes: supported, |
|
|
|
supportedResponseTypes: supported, |
|
|
|
discoveryAllowedOrigins: c.DiscoveryAllowedOrigins, |
|
|
|
idTokensValidFor: value(c.IDTokensValidFor, 24*time.Hour), |
|
|
|
idTokensValidFor: value(c.IDTokensValidFor, 24*time.Hour), |
|
|
|
skipApproval: c.SkipApprovalScreen, |
|
|
|
skipApproval: c.SkipApprovalScreen, |
|
|
|
now: now, |
|
|
|
now: now, |
|
|
|
templates: tmpls, |
|
|
|
templates: tmpls, |
|
|
|
logger: c.Logger, |
|
|
|
logger: c.Logger, |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for _, conn := range c.Connectors { |
|
|
|
for _, conn := range c.Connectors { |
|
|
|
@ -205,24 +203,29 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) |
|
|
|
handleFunc := func(p string, h http.HandlerFunc) { |
|
|
|
handleFunc := func(p string, h http.HandlerFunc) { |
|
|
|
r.HandleFunc(path.Join(issuerURL.Path, p), h) |
|
|
|
r.HandleFunc(path.Join(issuerURL.Path, p), h) |
|
|
|
} |
|
|
|
} |
|
|
|
handle := func(p string, h http.Handler) { |
|
|
|
|
|
|
|
r.Handle(path.Join(issuerURL.Path, p), h) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
handlePrefix := func(p string, h http.Handler) { |
|
|
|
handlePrefix := func(p string, h http.Handler) { |
|
|
|
prefix := path.Join(issuerURL.Path, p) |
|
|
|
prefix := path.Join(issuerURL.Path, p) |
|
|
|
r.PathPrefix(prefix).Handler(http.StripPrefix(prefix, h)) |
|
|
|
r.PathPrefix(prefix).Handler(http.StripPrefix(prefix, h)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
handleWithCORS := func(p string, h http.HandlerFunc) { |
|
|
|
|
|
|
|
var handler http.Handler = h |
|
|
|
|
|
|
|
if len(c.AllowedOrigins) > 0 { |
|
|
|
|
|
|
|
corsOption := handlers.AllowedOrigins(c.AllowedOrigins) |
|
|
|
|
|
|
|
handler = handlers.CORS(corsOption)(handler) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
r.Handle(path.Join(issuerURL.Path, p), handler) |
|
|
|
|
|
|
|
} |
|
|
|
r.NotFoundHandler = http.HandlerFunc(http.NotFound) |
|
|
|
r.NotFoundHandler = http.HandlerFunc(http.NotFound) |
|
|
|
|
|
|
|
|
|
|
|
discoveryHandler, err := s.discoveryHandler() |
|
|
|
discoveryHandler, err := s.discoveryHandler() |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
handle("/.well-known/openid-configuration", discoveryHandler) |
|
|
|
handleWithCORS("/.well-known/openid-configuration", discoveryHandler) |
|
|
|
|
|
|
|
|
|
|
|
// TODO(ericchiang): rate limit certain paths based on IP.
|
|
|
|
// TODO(ericchiang): rate limit certain paths based on IP.
|
|
|
|
handleFunc("/token", s.handleToken) |
|
|
|
handleWithCORS("/token", s.handleToken) |
|
|
|
handleFunc("/keys", s.handlePublicKeys) |
|
|
|
handleWithCORS("/keys", s.handlePublicKeys) |
|
|
|
handleFunc("/auth", s.handleAuthorization) |
|
|
|
handleFunc("/auth", s.handleAuthorization) |
|
|
|
handleFunc("/auth/{connector}", s.handleConnectorLogin) |
|
|
|
handleFunc("/auth/{connector}", s.handleConnectorLogin) |
|
|
|
handleFunc("/callback", s.handleConnectorCallback) |
|
|
|
handleFunc("/callback", s.handleConnectorCallback) |
|
|
|
|