Merge pull request #521 from ericchiang/allow-dex-to-work-at-non-base-url
Allow dex to work at non base url
This commit is contained in:
commit
d1bb106f94
8 changed files with 56 additions and 29 deletions
|
@ -54,10 +54,14 @@ In order to use the `oidc` connector you must register dex as an OIDC client; th
|
|||
When registering dex as a client, you need to provide redirect URLs to the provider. dex requires just one:
|
||||
|
||||
```
|
||||
https://$DEX_HOST:$DEX_PORT/auth/$CONNECTOR_ID/callback
|
||||
$ISSUER_URL/auth/$CONNECTOR_ID/callback
|
||||
```
|
||||
|
||||
`$DEX_HOST` and `$DEX_PORT` are the host and port of your dex installation. `$CONNECTOR_ID` is the `id` field of the connector for this OIDC provider.
|
||||
For example runnning a connector with ID `"google"` and an issuer URL of `"https://auth.example.com/foo"` the redirect would be.
|
||||
|
||||
```
|
||||
https://auth.example.com/foo/auth/google/callback
|
||||
```
|
||||
|
||||
Here's what a `oidc` connector looks like configured for authenticating with Google; the clientID and clientSecret shown are not usable. We consider Google a trusted email provider because the email address that is present in claims is for a Google provisioned email account (eg. an `@gmail.com` address)
|
||||
|
||||
|
@ -82,10 +86,14 @@ This connector config lets users authenticate through [GitHub](https://github.co
|
|||
To begin, register an OAuth application with GitHub through your, or your organization's [account settings](ttps://github.com/settings/applications/new). To register dex as a client of your GitHub application, enter dex's redirect URL under 'Authorization callback URL':
|
||||
|
||||
```
|
||||
https://$DEX_HOST:$DEX_PORT/auth/$CONNECTOR_ID/callback
|
||||
$ISSUER_URL/auth/$CONNECTOR_ID/callback
|
||||
```
|
||||
|
||||
`$DEX_HOST` and `$DEX_PORT` are the host and port of your dex installation. `$CONNECTOR_ID` is the `id` field of the connector.
|
||||
For example runnning a connector with ID `"github"` and an issuer URL of `"https://auth.example.com/bar"` the redirect would be.
|
||||
|
||||
```
|
||||
https://auth.example.com/bar/auth/github/callback
|
||||
```
|
||||
|
||||
Here's an example of a `github` connector; the clientID and clientSecret should be replaced by values provided by GitHub.
|
||||
|
||||
|
@ -113,10 +121,14 @@ __NOTE:__ When configuring a consumer through Bitbucket you _must_ configure rea
|
|||
To register dex as a client of your Bitbucket consumer, enter dex's redirect URL under 'Callback URL':
|
||||
|
||||
```
|
||||
https://$DEX_HOST:$DEX_PORT/auth/$CONNECTOR_ID/callback
|
||||
$ISSUER_URL/auth/$CONNECTOR_ID/callback
|
||||
```
|
||||
|
||||
`$DEX_HOST` and `$DEX_PORT` are the host and port of your dex installation. `$CONNECTOR_ID` is the `id` field of the connector.
|
||||
For example runnning a connector with ID `"bitbucket"` and an issuer URL of `"https://auth.example.com/spaz"` the redirect would be.
|
||||
|
||||
```
|
||||
https://auth.example.com/spaz/auth/bitbucket/callback
|
||||
```
|
||||
|
||||
Here's an example of a `bitbucket` connector; the clientID and clientSecret should be replaced by values provided by Bitbucket.
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ func main() {
|
|||
fs := flag.NewFlagSet("dex-worker", flag.ExitOnError)
|
||||
listen := fs.String("listen", "http://127.0.0.1:5556", "the address that the server will listen on")
|
||||
|
||||
issuer := fs.String("issuer", "http://127.0.0.1:5556", "the issuer's location")
|
||||
issuer := fs.String("issuer", "http://127.0.0.1:5556/dex", "the issuer's location")
|
||||
|
||||
certFile := fs.String("tls-cert-file", "", "the server's certificate file for TLS connection")
|
||||
keyFile := fs.String("tls-key-file", "", "the server's private key file for TLS connection")
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -43,7 +44,7 @@ func main() {
|
|||
certFile := fs.String("tls-cert-file", "", "the TLS cert file. If empty, the app will listen on HTTP")
|
||||
keyFile := fs.String("tls-key-file", "", "the TLS key file. If empty, the app will listen on HTTP")
|
||||
|
||||
discovery := fs.String("discovery", "http://127.0.0.1:5556", "")
|
||||
discovery := fs.String("discovery", "http://127.0.0.1:5556/dex", "")
|
||||
logDebug := fs.Bool("log-debug", false, "log debug-level information")
|
||||
logTimestamps := fs.Bool("log-timestamps", false, "prefix log lines with timestamps")
|
||||
|
||||
|
@ -181,7 +182,7 @@ func NewClientHandler(c *oidc.Client, issuer string, cbURL url.URL) http.Handler
|
|||
}
|
||||
|
||||
resendURL := *issuerURL
|
||||
resendURL.Path = "/resend-verify-email"
|
||||
resendURL.Path = path.Join(resendURL.Path, "/resend-verify-email")
|
||||
|
||||
mux.HandleFunc("/resend", handleResendFunc(c, *issuerURL, resendURL, cbURL))
|
||||
return mux
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/dex/connector"
|
||||
|
@ -336,7 +337,7 @@ func getConnectorForUserByEmail(ur user.UserRepo, email string) (string, error)
|
|||
func newLoginURLFromSession(issuer url.URL, ses *session.Session, register bool, connectorFilter []string, msgCode string) *url.URL {
|
||||
loginURL := issuer
|
||||
v := loginURL.Query()
|
||||
loginURL.Path = httpPathAuth
|
||||
loginURL.Path = path.Join(loginURL.Path, httpPathAuth)
|
||||
v.Set("redirect_uri", ses.RedirectURL.String())
|
||||
v.Set("state", ses.ClientState)
|
||||
v.Set("client_id", ses.ClientID)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"net/url"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/go-oidc/jose"
|
||||
|
@ -214,41 +215,53 @@ func (s *Server) HTTPHandler() http.Handler {
|
|||
|
||||
clock := clockwork.NewRealClock()
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc(httpPathDiscovery, handleDiscoveryFunc(s.ProviderConfig()))
|
||||
mux.HandleFunc(httpPathAuth, handleAuthFunc(s, s.Connectors, s.LoginTemplate, s.EnableRegistration))
|
||||
mux.HandleFunc(httpPathOOB, handleOOBFunc(s, s.OOBTemplate))
|
||||
mux.HandleFunc(httpPathToken, handleTokenFunc(s))
|
||||
mux.HandleFunc(httpPathKeys, handleKeysFunc(s.KeyManager, clock))
|
||||
mux.Handle(httpPathHealth, makeHealthHandler(checks))
|
||||
handle := func(urlPath string, h http.Handler) {
|
||||
p := path.Join(s.IssuerURL.Path, urlPath)
|
||||
// path.Join always trims trailing slashes (https://play.golang.org/p/GRr0jDd9P7).
|
||||
// If path being registered has a trailing slash, add it back on.
|
||||
if strings.HasSuffix(urlPath, "/") {
|
||||
p = p + "/"
|
||||
}
|
||||
mux.Handle(p, h)
|
||||
}
|
||||
handleFunc := func(urlPath string, hf http.HandlerFunc) {
|
||||
handle(urlPath, hf)
|
||||
}
|
||||
handleFunc(httpPathDiscovery, handleDiscoveryFunc(s.ProviderConfig()))
|
||||
handleFunc(httpPathAuth, handleAuthFunc(s, s.Connectors, s.LoginTemplate, s.EnableRegistration))
|
||||
handleFunc(httpPathOOB, handleOOBFunc(s, s.OOBTemplate))
|
||||
handleFunc(httpPathToken, handleTokenFunc(s))
|
||||
handleFunc(httpPathKeys, handleKeysFunc(s.KeyManager, clock))
|
||||
handle(httpPathHealth, makeHealthHandler(checks))
|
||||
|
||||
if s.EnableRegistration {
|
||||
mux.HandleFunc(httpPathRegister, handleRegisterFunc(s, s.RegisterTemplate))
|
||||
handleFunc(httpPathRegister, handleRegisterFunc(s, s.RegisterTemplate))
|
||||
}
|
||||
|
||||
mux.HandleFunc(httpPathEmailVerify, handleEmailVerifyFunc(s.VerifyEmailTemplate,
|
||||
handleFunc(httpPathEmailVerify, handleEmailVerifyFunc(s.VerifyEmailTemplate,
|
||||
s.IssuerURL, s.KeyManager.PublicKeys, s.UserManager))
|
||||
|
||||
mux.Handle(httpPathVerifyEmailResend, s.NewClientTokenAuthHandler(handleVerifyEmailResendFunc(s.IssuerURL,
|
||||
handle(httpPathVerifyEmailResend, s.NewClientTokenAuthHandler(handleVerifyEmailResendFunc(s.IssuerURL,
|
||||
s.KeyManager.PublicKeys,
|
||||
s.UserEmailer,
|
||||
s.UserRepo,
|
||||
s.ClientManager)))
|
||||
|
||||
mux.Handle(httpPathSendResetPassword, &SendResetPasswordEmailHandler{
|
||||
handle(httpPathSendResetPassword, &SendResetPasswordEmailHandler{
|
||||
tpl: s.SendResetPasswordEmailTemplate,
|
||||
emailer: s.UserEmailer,
|
||||
sm: s.SessionManager,
|
||||
cm: s.ClientManager,
|
||||
})
|
||||
|
||||
mux.Handle(httpPathResetPassword, &ResetPasswordHandler{
|
||||
handle(httpPathResetPassword, &ResetPasswordHandler{
|
||||
tpl: s.ResetPasswordTemplate,
|
||||
issuerURL: s.IssuerURL,
|
||||
um: s.UserManager,
|
||||
keysFunc: s.KeyManager.PublicKeys,
|
||||
})
|
||||
|
||||
mux.Handle(httpPathAcceptInvitation, &InvitationHandler{
|
||||
handle(httpPathAcceptInvitation, &InvitationHandler{
|
||||
passwordResetURL: s.absURL(httpPathResetPassword),
|
||||
issuerURL: s.IssuerURL,
|
||||
um: s.UserManager,
|
||||
|
@ -258,10 +271,10 @@ func (s *Server) HTTPHandler() http.Handler {
|
|||
})
|
||||
|
||||
if s.EnableClientRegistration {
|
||||
mux.HandleFunc(httpPathClientRegistration, s.handleClientRegistration)
|
||||
handleFunc(httpPathClientRegistration, s.handleClientRegistration)
|
||||
}
|
||||
|
||||
mux.HandleFunc(httpPathDebugVars, health.ExpvarHandler)
|
||||
handleFunc(httpPathDebugVars, health.ExpvarHandler)
|
||||
|
||||
pcfg := s.ProviderConfig()
|
||||
for _, idpc := range s.Connectors {
|
||||
|
@ -271,7 +284,7 @@ func (s *Server) HTTPHandler() http.Handler {
|
|||
}
|
||||
// NOTE(ericchiang): This path MUST end in a "/" in order to indicate a
|
||||
// path prefix rather than an absolute path.
|
||||
mux.Handle(path.Join(httpPathAuth, idpc.ID())+"/", idpc.Handler(*errorURL))
|
||||
handle(path.Join(httpPathAuth, idpc.ID())+"/", idpc.Handler(*errorURL))
|
||||
}
|
||||
|
||||
apiBasePath := path.Join(httpPathAPI, APIVersion)
|
||||
|
@ -280,7 +293,7 @@ func (s *Server) HTTPHandler() http.Handler {
|
|||
usersAPI := usersapi.NewUsersAPI(s.UserManager, s.ClientManager, s.RefreshTokenRepo, s.UserEmailer, s.localConnectorID)
|
||||
handler := NewUserMgmtServer(usersAPI, s.JWTVerifierFactory(), s.UserManager, s.ClientManager).HTTPHandler()
|
||||
|
||||
mux.Handle(apiBasePath+"/", handler)
|
||||
handle(apiBasePath+"/", handler)
|
||||
|
||||
return http.Handler(mux)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<div class="panel">
|
||||
<h2 class="heading">Log in to Your Account</h2>
|
||||
<form method="post" action="{{.PostURL | absPath }}">
|
||||
<form method="post" action="{{ .PostURL }}">
|
||||
<div class="form-row">
|
||||
LDAP
|
||||
<div class="input-desc">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<div class="panel">
|
||||
<h2 class="heading">Log in to Your Account</h2>
|
||||
<form method="post" action="{{.PostURL | absPath}}">
|
||||
<form method="post" action="{{ .PostURL }}">
|
||||
<div class="form-row">
|
||||
<div class="input-desc">
|
||||
<label for="userid">Email Address</label>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
{{ end }}
|
||||
{{ else }}
|
||||
<h2 class="heading">Reset your password</h2>
|
||||
<form onsubmit="return validate();" id="resetPasswordForm" method="POST" action="/reset-password">
|
||||
<form onsubmit="return validate();" id="resetPasswordForm" method="POST" action="{{ "/reset-password" | absPath }}">
|
||||
<div class="form-row">
|
||||
<div class="input-desc">
|
||||
<label for="password">New Password</label>
|
||||
|
|
Reference in a new issue