Add Auth0 to supported OAuth2 providers
Auth0 is an OpenID Connect compliant OAuth2 provider, so we're able to re-use the generic OAuth2 provider to implement it. The routes required by Auth0 have been hardcoded for user convenience. Also, Auth0 requires users to register a subdomain of auth0.com when signing up. This must be provided to chronograf through the `--auth0-domain` parameter (or `AUTH0_DOMAIN` ENV). This is **distinct** from the `PUBLIC_URL`. For example, for a Chronograf hosted at `http://www.example.com`, and an Auth0 domain of `http://oceanic-airlines.auth0.com`, a client-id of `notpennysboat` and a client-secret of `4-8-15-16-23-42`, the command line options would look like: ``` chronograf \ --auth0-domain=http://oceanic-airlines.auth0.com \ --auth0-client-id=notpennysboat \ --auth0-secret=4-8-15-16-23-24 --public-url=http://www.example.com -t `uuidgen` ```pull/10616/head
parent
34808ddb9d
commit
6c8e889b03
|
@ -0,0 +1,47 @@
|
|||
package oauth2
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"github.com/influxdata/chronograf"
|
||||
)
|
||||
|
||||
type Auth0 struct {
|
||||
Generic
|
||||
}
|
||||
|
||||
func NewAuth0(auth0Domain, clientID, clientSecret, redirectURL string, logger chronograf.Logger) (Auth0, error) {
|
||||
domain, err := url.Parse(auth0Domain)
|
||||
if err != nil {
|
||||
return Auth0{}, err
|
||||
}
|
||||
|
||||
domain.Scheme = "https"
|
||||
|
||||
domain.Path = "/authorize"
|
||||
authURL := domain.String()
|
||||
|
||||
domain.Path = "/oauth/token"
|
||||
tokenURL := domain.String()
|
||||
|
||||
domain.Path = "/userinfo"
|
||||
apiURL := domain.String()
|
||||
|
||||
return Auth0{
|
||||
Generic: Generic{
|
||||
PageName: "auth0",
|
||||
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
|
||||
RequiredScopes: []string{"openid"},
|
||||
|
||||
RedirectURL: redirectURL,
|
||||
AuthURL: authURL,
|
||||
TokenURL: tokenURL,
|
||||
APIURL: apiURL,
|
||||
|
||||
Logger: logger,
|
||||
},
|
||||
}, nil
|
||||
}
|
|
@ -80,6 +80,10 @@ type Server struct {
|
|||
|
||||
StatusFeedURL string `long:"status-feed-url" description:"URL of a JSON Feed to display as a News Feed on the client Status page." default:"https://www.influxdata.com/feed/json" env:"STATUS_FEED_URL"`
|
||||
|
||||
Auth0Domain string `long:"auth0-domain" description:"Subdomain of auth0.com used for Auth0 OAuth2 authentication" env:"AUTH0_DOMAIN"`
|
||||
Auth0ClientID string `long:"auth0-client-id" description:"Auth0 Client ID for OAuth2 support" env:"AUTH0_CLIENT_ID"`
|
||||
Auth0ClientSecret string `long:"auth0-client-secret" description:"Auth0 Client Secret for OAuth2 support" env:"AUTH0_CLIENT_SECRET"`
|
||||
|
||||
ReportingDisabled bool `short:"r" long:"reporting-disabled" description:"Disable reporting of usage stats (os,arch,version,cluster_id,uptime) once every 24hr" env:"REPORTING_DISABLED"`
|
||||
LogLevel string `short:"l" long:"log-level" value-name:"choice" choice:"debug" choice:"info" choice:"error" default:"info" description:"Set the logging level" env:"LOG_LEVEL"`
|
||||
Basepath string `short:"p" long:"basepath" description:"A URL path prefix under which all chronograf routes will be mounted" env:"BASE_PATH"`
|
||||
|
@ -113,6 +117,10 @@ func (s *Server) UseHeroku() bool {
|
|||
return s.TokenSecret != "" && s.HerokuClientID != "" && s.HerokuSecret != ""
|
||||
}
|
||||
|
||||
func (s *Server) UseAuth0() bool {
|
||||
return s.Auth0ClientID != "" && s.Auth0ClientSecret != ""
|
||||
}
|
||||
|
||||
// UseGenericOAuth2 validates the CLI parameters to enable generic oauth support
|
||||
func (s *Server) UseGenericOAuth2() bool {
|
||||
return s.TokenSecret != "" && s.GenericClientID != "" &&
|
||||
|
@ -176,6 +184,27 @@ func (s *Server) genericOAuth(logger chronograf.Logger, auth oauth2.Authenticato
|
|||
return &gen, genMux, s.UseGenericOAuth2
|
||||
}
|
||||
|
||||
func (s *Server) auth0OAuth(logger chronograf.Logger, auth oauth2.Authenticator) (oauth2.Provider, oauth2.Mux, func() bool) {
|
||||
redirectPath := path.Join(s.Basepath, "oauth", "auth0", "callback")
|
||||
redirectURL, err := url.Parse(s.PublicURL)
|
||||
if err != nil {
|
||||
logger.Error("Error parsing public URL: err:", err)
|
||||
return &oauth2.Auth0{}, &oauth2.AuthMux{}, func() bool { return false }
|
||||
}
|
||||
redirectURL.Path = redirectPath
|
||||
|
||||
auth0, err := oauth2.NewAuth0(s.Auth0Domain, s.Auth0ClientID, s.Auth0ClientSecret, redirectURL.String(), logger)
|
||||
|
||||
jwt := oauth2.NewJWT(s.TokenSecret)
|
||||
genMux := oauth2.NewAuthMux(&auth0, auth, jwt, s.Basepath, logger)
|
||||
|
||||
if err != nil {
|
||||
logger.Error("Error parsing Auth0 domain: err:", err)
|
||||
return &auth0, genMux, func() bool { return false }
|
||||
}
|
||||
return &auth0, genMux, s.UseAuth0
|
||||
}
|
||||
|
||||
func (s *Server) genericRedirectURL() string {
|
||||
if s.PublicURL == "" {
|
||||
return ""
|
||||
|
@ -202,7 +231,7 @@ type BuildInfo struct {
|
|||
}
|
||||
|
||||
func (s *Server) useAuth() bool {
|
||||
return s.UseGithub() || s.UseGoogle() || s.UseHeroku() || s.UseGenericOAuth2()
|
||||
return s.UseGithub() || s.UseGoogle() || s.UseHeroku() || s.UseGenericOAuth2() || s.UseAuth0()
|
||||
}
|
||||
|
||||
func (s *Server) useTLS() bool {
|
||||
|
@ -273,6 +302,7 @@ func (s *Server) Serve(ctx context.Context) error {
|
|||
providerFuncs = append(providerFuncs, provide(s.googleOAuth(logger, auth)))
|
||||
providerFuncs = append(providerFuncs, provide(s.herokuOAuth(logger, auth)))
|
||||
providerFuncs = append(providerFuncs, provide(s.genericOAuth(logger, auth)))
|
||||
providerFuncs = append(providerFuncs, provide(s.auth0OAuth(logger, auth)))
|
||||
|
||||
s.handler = NewMux(MuxOpts{
|
||||
Develop: s.Develop,
|
||||
|
|
Loading…
Reference in New Issue