git.iko.soy/typeable/oauth2-proxy
on v1.0 help sign in
99 lines 3.5 kB history raw
1package main
3import (
4 "flag"
5 "fmt"
6 "log"
7 "net"
8 "net/http"
9 "os"
10 "strings"
11 "time"
13 "github.com/BurntSushi/toml"
14 "github.com/mreiferson/go-options"
17func main() {
18 flagSet := flag.NewFlagSet("google_auth_proxy", flag.ExitOnError)
20 googleAppsDomains := StringArray{}
21 upstreams := StringArray{}
23 config := flagSet.String("config", "", "path to config file")
24 showVersion := flagSet.Bool("version", false, "print version string")
26 flagSet.String("http-address", "127.0.0.1:4180", "<addr>:<port> to listen on for HTTP clients")
27 flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
28 flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint. If multiple, routing is based on path")
29 flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
31 flagSet.Var(&googleAppsDomains, "google-apps-domain", "authenticate against the given Google apps domain (may be given multiple times)")
32 flagSet.String("client-id", "", "the Google OAuth Client ID: ie: \"123456.apps.googleusercontent.com\"")
33 flagSet.String("client-secret", "", "the OAuth Client Secret")
34 flagSet.String("authenticated-emails-file", "", "authenticate against emails via file (one per line)")
35 flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -s\" for SHA encryption")
37 flagSet.String("cookie-secret", "", "the seed string for secure cookies")
38 flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*")
39 flagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie")
40 flagSet.Bool("cookie-https-only", true, "set HTTPS only cookie")
42 flagSet.Parse(os.Args[1:])
44 if *showVersion {
45 fmt.Printf("google_auth_proxy v%s\n", VERSION)
46 return
47 }
49 opts := NewOptions()
51 var cfg map[string]interface{}
52 if *config != "" {
53 _, err := toml.DecodeFile(*config, &cfg)
54 if err != nil {
55 log.Fatalf("ERROR: failed to load config file %s - %s", *config, err)
56 }
57 }
58 LoadOptionsFromEnv(opts, cfg)
59 options.Resolve(opts, flagSet, cfg)
61 err := opts.Validate()
62 if err != nil {
63 log.Printf("%s", err)
64 os.Exit(1)
65 }
67 validator := NewValidator(opts.GoogleAppsDomains, opts.AuthenticatedEmailsFile)
68 oauthproxy := NewOauthProxy(opts, validator)
70 if len(opts.GoogleAppsDomains) != 0 && opts.AuthenticatedEmailsFile == "" {
71 if len(opts.GoogleAppsDomains) > 1 {
72 oauthproxy.SignInMessage = fmt.Sprintf("Authenticate using one of the following domains: %v", strings.Join(opts.GoogleAppsDomains, ", "))
73 } else {
74 oauthproxy.SignInMessage = fmt.Sprintf("Authenticate using %v", opts.GoogleAppsDomains[0])
75 }
76 }
78 if opts.HtpasswdFile != "" {
79 log.Printf("using htpasswd file %s", opts.HtpasswdFile)
80 oauthproxy.HtpasswdFile, err = NewHtpasswdFromFile(opts.HtpasswdFile)
81 if err != nil {
82 log.Fatalf("FATAL: unable to open %s %s", opts.HtpasswdFile, err)
83 }
84 }
86 listener, err := net.Listen("tcp", opts.HttpAddress)
87 if err != nil {
88 log.Fatalf("FATAL: listen (%s) failed - %s", opts.HttpAddress, err)
89 }
90 log.Printf("listening on %s", opts.HttpAddress)
92 server := &http.Server{Handler: oauthproxy}
93 err = server.Serve(listener)
94 if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
95 log.Printf("ERROR: http.Serve() - %s", err)
96 }
98 log.Printf("HTTP: closing %s", listener.Addr())