Enable specific oauth2proxy path; change cookie name to _oauth2proxy

This commit is contained in:
tonymeng 2015-05-29 15:47:40 -07:00 committed by Jehiah Czebotar
parent 71b79baf33
commit c5ccd43767
6 changed files with 40 additions and 18 deletions

View File

@ -90,17 +90,20 @@ An example [oauth2_proxy.cfg](contrib/oauth2_proxy.cfg.example) config file is i
Usage of oauth2_proxy: Usage of oauth2_proxy:
-authenticated-emails-file="": authenticate against emails via file (one per line) -authenticated-emails-file="": authenticate against emails via file (one per line)
-client-id="": the OAuth Client ID: ie: "123456.apps.googleusercontent.com" -client-id="": the OAuth Client ID: ie: "123456.apps.googleusercontent.com"
-client-secret="": the Client Secret -client-secret="": the OAuth Client Secret
-config="": path to config file -config="": path to config file
-cookie-domain="": an optional cookie domain to force cookies to (ie: .yourcompany.com)* -cookie-domain="": an optional cookie domain to force cookies to (ie: .yourcompany.com)*
-cookie-expire=168h0m0s: expire timeframe for cookie -cookie-expire=168h0m0s: expire timeframe for cookie
-cookie-httponly=true: set HttpOnly cookie flag -cookie-httponly=true: set HttpOnly cookie flag
-cookie-https-only=true: set secure (HTTPS) cookies (deprecated. use --cookie-secure setting) -cookie-https-only=true: set secure (HTTPS) cookies (deprecated. use --cookie-secure setting)
-cookie-key="_oauth2proxy": the name of the cookie that the oauth_proxy creates
-cookie-refresh=0: refresh the cookie when less than this much time remains before expiration; 0 to disable -cookie-refresh=0: refresh the cookie when less than this much time remains before expiration; 0 to disable
-cookie-secret="": the seed string for secure cookies -cookie-secret="": the seed string for secure cookies
-cookie-secure=true: set secure (HTTPS) cookie flag -cookie-secure=true: set secure (HTTPS) cookie flag
-custom-templates-dir="": path to custom html templates -custom-templates-dir="": path to custom html templates
-display-htpasswd-form=true: display username / password login form if an htpasswd file is provided -display-htpasswd-form=true: display username / password login form if an htpasswd file is provided
-github-org="": restrict logins to members of this organisation
-github-team="": restrict logins to members of this team
-google-apps-domain=: authenticate against the given Google apps domain (may be given multiple times) -google-apps-domain=: authenticate against the given Google apps domain (may be given multiple times)
-htpasswd-file="": additionally authenticate against a htpasswd file. Entries must be created with "htpasswd -s" for SHA encryption -htpasswd-file="": additionally authenticate against a htpasswd file. Entries must be created with "htpasswd -s" for SHA encryption
-http-address="127.0.0.1:4180": [http://]<addr>:<port> or unix://<path> to listen on for HTTP clients -http-address="127.0.0.1:4180": [http://]<addr>:<port> or unix://<path> to listen on for HTTP clients
@ -110,6 +113,7 @@ Usage of oauth2_proxy:
-pass-host-header=true: pass the request Host Header to upstream -pass-host-header=true: pass the request Host Header to upstream
-profile-url="": Profile access endpoint -profile-url="": Profile access endpoint
-provider="": Oauth provider (defaults to Google) -provider="": Oauth provider (defaults to Google)
-proxy-prefix="/oauth2": the url root path that this proxy should be nested under (e.g. /<oauth2>/sign_in)
-redeem-url="": Token redemption endpoint -redeem-url="": Token redemption endpoint
-redirect-url="": the OAuth Redirect URL. ie: "https://internalapp.yourcompany.com/oauth2/callback" -redirect-url="": the OAuth Redirect URL. ie: "https://internalapp.yourcompany.com/oauth2/callback"
-request-logging=true: Log requests to stdout -request-logging=true: Log requests to stdout

View File

@ -47,6 +47,7 @@
# custom_templates_dir = "" # custom_templates_dir = ""
## Cookie Settings ## Cookie Settings
## Key - the cookie name
## Secret - the seed string for secure cookies; should be 16, 24, or 32 bytes ## Secret - the seed string for secure cookies; should be 16, 24, or 32 bytes
## for use with an AES cipher when cookie_refresh or pass_access_token ## for use with an AES cipher when cookie_refresh or pass_access_token
## is set ## is set
@ -57,6 +58,7 @@
## Refresh revalidated the OAuth token to ensure it is still valid. ie: 24h ## Refresh revalidated the OAuth token to ensure it is still valid. ie: 24h
## Secure - secure cookies are only sent by the browser of a HTTPS connection (recommended) ## Secure - secure cookies are only sent by the browser of a HTTPS connection (recommended)
## HttpOnly - httponly cookies are not readable by javascript (recommended) ## HttpOnly - httponly cookies are not readable by javascript (recommended)
# cookie_key = "_oauth2proxy"
# cookie_secret = "" # cookie_secret = ""
# cookie_domain = "" # cookie_domain = ""
# cookie_expire = "168h" # cookie_expire = "168h"

View File

@ -44,7 +44,9 @@ func main() {
flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -s\" for SHA encryption") flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -s\" for SHA encryption")
flagSet.Bool("display-htpasswd-form", true, "display username / password login form if an htpasswd file is provided") flagSet.Bool("display-htpasswd-form", true, "display username / password login form if an htpasswd file is provided")
flagSet.String("custom-templates-dir", "", "path to custom html templates") flagSet.String("custom-templates-dir", "", "path to custom html templates")
flagSet.String("proxy-prefix", "/oauth2", "the url root path that this proxy should be nested under (e.g. /<oauth2>/sign_in)")
flagSet.String("cookie-key", "_oauth2proxy", "the name of the cookie that the oauth_proxy creates")
flagSet.String("cookie-secret", "", "the seed string for secure cookies") flagSet.String("cookie-secret", "", "the seed string for secure cookies")
flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*") flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*")
flagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie") flagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie")

View File

@ -19,12 +19,6 @@ import (
"github.com/bitly/oauth2_proxy/providers" "github.com/bitly/oauth2_proxy/providers"
) )
const robotsPath = "/robots.txt"
const pingPath = "/ping"
const signInPath = "/oauth2/sign_in"
const oauthStartPath = "/oauth2/start"
const oauthCallbackPath = "/oauth2/callback"
type OauthProxy struct { type OauthProxy struct {
CookieSeed string CookieSeed string
CookieKey string CookieKey string
@ -35,6 +29,12 @@ type OauthProxy struct {
CookieRefresh time.Duration CookieRefresh time.Duration
Validator func(string) bool Validator func(string) bool
RobotsPath string
PingPath string
SignInPath string
OauthStartPath string
OauthCallbackPath string
redirectUrl *url.URL // the url to receive requests at redirectUrl *url.URL // the url to receive requests at
provider providers.Provider provider providers.Provider
oauthLoginUrl *url.URL // to redirect the user to oauthLoginUrl *url.URL // to redirect the user to
@ -42,6 +42,7 @@ type OauthProxy struct {
oauthScope string oauthScope string
clientID string clientID string
clientSecret string clientSecret string
ProxyPrefix string
SignInMessage string SignInMessage string
HtpasswdFile *HtpasswdFile HtpasswdFile *HtpasswdFile
DisplayHtpasswdForm bool DisplayHtpasswdForm bool
@ -106,7 +107,7 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy {
} }
redirectUrl := opts.redirectUrl redirectUrl := opts.redirectUrl
redirectUrl.Path = oauthCallbackPath redirectUrl.Path = fmt.Sprintf("%s/callback", opts.ProxyPrefix)
log.Printf("OauthProxy configured for %s", opts.ClientID) log.Printf("OauthProxy configured for %s", opts.ClientID)
domain := opts.CookieDomain domain := opts.CookieDomain
@ -131,7 +132,7 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy {
} }
return &OauthProxy{ return &OauthProxy{
CookieKey: "_oauthproxy", CookieKey: opts.CookieKey,
CookieSeed: opts.CookieSecret, CookieSeed: opts.CookieSecret,
CookieDomain: opts.CookieDomain, CookieDomain: opts.CookieDomain,
CookieSecure: opts.CookieSecure, CookieSecure: opts.CookieSecure,
@ -140,8 +141,15 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy {
CookieRefresh: opts.CookieRefresh, CookieRefresh: opts.CookieRefresh,
Validator: validator, Validator: validator,
RobotsPath: "/robots.txt",
PingPath: "/ping",
SignInPath: fmt.Sprintf("%s/sign_in", opts.ProxyPrefix),
OauthStartPath: fmt.Sprintf("%s/start", opts.ProxyPrefix),
OauthCallbackPath: fmt.Sprintf("%s/callback", opts.ProxyPrefix),
clientID: opts.ClientID, clientID: opts.ClientID,
clientSecret: opts.ClientSecret, clientSecret: opts.ClientSecret,
ProxyPrefix: opts.ProxyPrefix,
oauthScope: opts.provider.Data().Scope, oauthScope: opts.provider.Data().Scope,
provider: opts.provider, provider: opts.provider,
oauthLoginUrl: opts.provider.Data().LoginUrl, oauthLoginUrl: opts.provider.Data().LoginUrl,
@ -300,7 +308,7 @@ func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
rw.WriteHeader(code) rw.WriteHeader(code)
redirect_url := req.URL.RequestURI() redirect_url := req.URL.RequestURI()
if redirect_url == signInPath { if redirect_url == p.SignInPath {
redirect_url = "/" redirect_url = "/"
} }
@ -310,12 +318,14 @@ func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
CustomLogin bool CustomLogin bool
Redirect string Redirect string
Version string Version string
ProxyPrefix string
}{ }{
ProviderName: p.provider.Data().ProviderName, ProviderName: p.provider.Data().ProviderName,
SignInMessage: p.SignInMessage, SignInMessage: p.SignInMessage,
CustomLogin: p.displayCustomLoginForm(), CustomLogin: p.displayCustomLoginForm(),
Redirect: redirect_url, Redirect: redirect_url,
Version: VERSION, Version: VERSION,
ProxyPrefix: p.ProxyPrefix,
} }
p.templates.ExecuteTemplate(rw, "sign_in.html", t) p.templates.ExecuteTemplate(rw, "sign_in.html", t)
} }
@ -365,12 +375,12 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
var email string var email string
var access_token string var access_token string
if req.URL.Path == robotsPath { if req.URL.Path == p.RobotsPath {
p.RobotsTxt(rw) p.RobotsTxt(rw)
return return
} }
if req.URL.Path == pingPath { if req.URL.Path == p.PingPath {
p.PingPage(rw) p.PingPage(rw)
return return
} }
@ -384,7 +394,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
} }
if req.URL.Path == signInPath { if req.URL.Path == p.SignInPath {
redirect, err := p.GetRedirect(req) redirect, err := p.GetRedirect(req)
if err != nil { if err != nil {
p.ErrorPage(rw, 500, "Internal Error", err.Error()) p.ErrorPage(rw, 500, "Internal Error", err.Error())
@ -400,7 +410,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
} }
return return
} }
if req.URL.Path == oauthStartPath { if req.URL.Path == p.OauthStartPath {
redirect, err := p.GetRedirect(req) redirect, err := p.GetRedirect(req)
if err != nil { if err != nil {
p.ErrorPage(rw, 500, "Internal Error", err.Error()) p.ErrorPage(rw, 500, "Internal Error", err.Error())
@ -409,7 +419,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
http.Redirect(rw, req, p.GetLoginURL(req.Host, redirect), 302) http.Redirect(rw, req, p.GetLoginURL(req.Host, redirect), 302)
return return
} }
if req.URL.Path == oauthCallbackPath { if req.URL.Path == p.OauthCallbackPath {
// finish the oauth cycle // finish the oauth cycle
err := req.ParseForm() err := req.ParseForm()
if err != nil { if err != nil {

View File

@ -12,6 +12,7 @@ import (
// Configuration Options that can be set by Command Line Flag, or Config File // Configuration Options that can be set by Command Line Flag, or Config File
type Options struct { type Options struct {
ProxyPrefix string `flag:"proxy-prefix" cfg:"proxy-prefix"`
HttpAddress string `flag:"http-address" cfg:"http_address"` HttpAddress string `flag:"http-address" cfg:"http_address"`
RedirectUrl string `flag:"redirect-url" cfg:"redirect_url"` RedirectUrl string `flag:"redirect-url" cfg:"redirect_url"`
ClientID string `flag:"client-id" cfg:"client_id" env:"OAUTH2_PROXY_CLIENT_ID"` ClientID string `flag:"client-id" cfg:"client_id" env:"OAUTH2_PROXY_CLIENT_ID"`
@ -25,6 +26,7 @@ type Options struct {
DisplayHtpasswdForm bool `flag:"display-htpasswd-form" cfg:"display_htpasswd_form"` DisplayHtpasswdForm bool `flag:"display-htpasswd-form" cfg:"display_htpasswd_form"`
CustomTemplatesDir string `flag:"custom-templates-dir" cfg:"custom_templates_dir"` CustomTemplatesDir string `flag:"custom-templates-dir" cfg:"custom_templates_dir"`
CookieKey string `flag:"cookie-key" cfg:"cookie_key" env:"OAUTH2_PROXY_COOKIE_KEY"`
CookieSecret string `flag:"cookie-secret" cfg:"cookie_secret" env:"OAUTH2_PROXY_COOKIE_SECRET"` CookieSecret string `flag:"cookie-secret" cfg:"cookie_secret" env:"OAUTH2_PROXY_COOKIE_SECRET"`
CookieDomain string `flag:"cookie-domain" cfg:"cookie_domain" env:"OAUTH2_PROXY_COOKIE_DOMAIN"` CookieDomain string `flag:"cookie-domain" cfg:"cookie_domain" env:"OAUTH2_PROXY_COOKIE_DOMAIN"`
CookieExpire time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"OAUTH2_PROXY_COOKIE_EXPIRE"` CookieExpire time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"OAUTH2_PROXY_COOKIE_EXPIRE"`
@ -59,8 +61,10 @@ type Options struct {
func NewOptions() *Options { func NewOptions() *Options {
return &Options{ return &Options{
ProxyPrefix: "/oauth2",
HttpAddress: "127.0.0.1:4180", HttpAddress: "127.0.0.1:4180",
DisplayHtpasswdForm: true, DisplayHtpasswdForm: true,
CookieKey: "_oauthproxy",
CookieHttpsOnly: true, CookieHttpsOnly: true,
CookieSecure: true, CookieSecure: true,
CookieHttpOnly: true, CookieHttpOnly: true,

View File

@ -110,7 +110,7 @@ func getTemplates() *template.Template {
</head> </head>
<body> <body>
<div class="signin center"> <div class="signin center">
<form method="GET" action="/oauth2/start"> <form method="GET" action="{{.ProxyPrefix}}/start">
<input type="hidden" name="rd" value="{{.Redirect}}"> <input type="hidden" name="rd" value="{{.Redirect}}">
{{ if .SignInMessage }} {{ if .SignInMessage }}
<p>{{.SignInMessage}}</p> <p>{{.SignInMessage}}</p>
@ -121,7 +121,7 @@ func getTemplates() *template.Template {
{{ if .CustomLogin }} {{ if .CustomLogin }}
<div class="signin"> <div class="signin">
<form method="POST" action="/oauth2/sign_in"> <form method="POST" action="{{.ProxyPrefix}}/sign_in">
<input type="hidden" name="rd" value="{{.Redirect}}"> <input type="hidden" name="rd" value="{{.Redirect}}">
<label for="username">Username:</label><input type="text" name="username" id="username" size="10"><br/> <label for="username">Username:</label><input type="text" name="username" id="username" size="10"><br/>
<label for="password">Password:</label><input type="password" name="password" id="password" size="10"><br/> <label for="password">Password:</label><input type="password" name="password" id="password" size="10"><br/>
@ -150,7 +150,7 @@ func getTemplates() *template.Template {
<h2>{{.Title}}</h2> <h2>{{.Title}}</h2>
<p>{{.Message}}</p> <p>{{.Message}}</p>
<hr> <hr>
<p><a href="/oauth2/sign_in">Sign In</a></p> <p><a href="{{.ProxyPrefix}}/sign_in">Sign In</a></p>
</body> </body>
</html>{{end}}`) </html>{{end}}`)
if err != nil { if err != nil {