Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[oidc-discovery-provider] Fix keys url #5690

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
bfbdeb3
[oidc-discovery-provider] Fix keys url
kfox1111 Dec 8, 2024
442a1c8
Update tests
kfox1111 Dec 8, 2024
6b33c7f
Merge branch 'main' into issuer-fix
kfox1111 Dec 15, 2024
29bdd98
Add advertised_url support
kfox1111 Dec 15, 2024
63d7981
Simplify change
kfox1111 Dec 15, 2024
f35e79b
Revert domain name check
kfox1111 Dec 15, 2024
6f5e7e9
Add prefix support
kfox1111 Dec 15, 2024
88e33bb
Cleanup
kfox1111 Dec 15, 2024
295ccc2
Fix typo
kfox1111 Dec 15, 2024
8800dba
Merge branch 'main' into issuer-fix
kfox1111 Dec 16, 2024
219ac45
Merge branch 'main' into issuer-fix
kfox1111 Dec 16, 2024
b88a3ae
Merge branch 'main' into issuer-fix
kfox1111 Dec 17, 2024
9bcf2dd
Merge branch 'main' into issuer-fix
kfox1111 Dec 19, 2024
d18d37d
Merge branch 'main' into issuer-fix
kfox1111 Jan 2, 2025
79865b8
Merge branch 'main' into issuer-fix
kfox1111 Jan 3, 2025
851dc3a
Merge branch 'main' into issuer-fix
kfox1111 Jan 3, 2025
dc97122
Merge branch 'main' into issuer-fix
kfox1111 Jan 13, 2025
d191da0
Update names after feedback
kfox1111 Jan 14, 2025
bc0b68e
Merge branch 'main' into issuer-fix
kfox1111 Jan 14, 2025
6d07e62
Merge branch 'main' into issuer-fix
kfox1111 Jan 15, 2025
8c7972b
Fix typo
kfox1111 Jan 15, 2025
e28186a
Incorperate feedback
kfox1111 Jan 20, 2025
462a7b2
Merge branch 'main' into issuer-fix
kfox1111 Jan 20, 2025
4675ec8
Merge branch 'main' into issuer-fix
kfox1111 Jan 20, 2025
ef0c4b5
Incorperate feedback
kfox1111 Jan 20, 2025
7da1b9f
Merge branch 'issuer-fix' of https://github.com/kfox1111/spire into i…
kfox1111 Jan 20, 2025
a448c12
Fix tests
kfox1111 Jan 21, 2025
96dee03
Fix test
kfox1111 Jan 21, 2025
1902ac9
Merge branch 'main' into issuer-fix
kfox1111 Jan 21, 2025
e6694f6
Incorperate feedback
kfox1111 Jan 21, 2025
38a2d49
Merge branch 'main' into issuer-fix
kfox1111 Jan 24, 2025
710d78b
Merge branch 'main' into issuer-fix
MarcosDY Jan 24, 2025
01709db
Incorperate feedback
kfox1111 Jan 24, 2025
3b80a00
Merge branch 'main' into issuer-fix
kfox1111 Jan 24, 2025
a438130
Incorperate feedback
kfox1111 Jan 29, 2025
bcf6e92
Merge branch 'issuer-fix' of https://github.com/kfox1111/spire into i…
kfox1111 Jan 29, 2025
fcb33ec
Merge branch 'main' into issuer-fix
kfox1111 Jan 29, 2025
35895d1
Add test for compat behavior. Fix lint.
kfox1111 Jan 29, 2025
dc7aa77
Merge branch 'issuer-fix' of https://github.com/kfox1111/spire into i…
kfox1111 Jan 29, 2025
e6814c5
Fix lint
kfox1111 Jan 29, 2025
9146d52
Merge branch 'main' into issuer-fix
kfox1111 Jan 30, 2025
7a5f5ac
Merge branch 'main' into issuer-fix
kfox1111 Jan 30, 2025
32465f0
Update docs
kfox1111 Jan 30, 2025
e6772f8
Merge branch 'issuer-fix' of https://github.com/kfox1111/spire into i…
kfox1111 Jan 30, 2025
a1df74d
Merge branch 'main' into issuer-fix
kfox1111 Jan 31, 2025
d74e535
Merge branch 'main' into issuer-fix
kfox1111 Feb 1, 2025
84dedb0
Merge branch 'main' into issuer-fix
kfox1111 Feb 3, 2025
3544966
Merge branch 'main' into issuer-fix
kfox1111 Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions support/oidc-discovery-provider/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ type Config struct {

// JWTIssuer specifies the issuer for the OIDC provider configuration request.
JWTIssuer string `hcl:"jwt_issuer"`

// JWKSURI specifies the absolute uri to the jwks keys document. Use this if you are fronting the
// discovery provider with a load balancer or reverse proxy
JWKSURI string `hcl:"jwks_uri"`

// ServerPathPrefix specifies the prefix to strip from the path of requests to route to the server.
// Example: if ServerPathPrefix is /foo then a request to http://127.0.0.1/foo/.well-known/openid-configuration and
// http://127.0.0.1/foo/keys will function with the server.
ServerPathPrefix string `hcl:"server_path_prefix"`
}

type ServingCertFileConfig struct {
Expand Down Expand Up @@ -308,6 +317,12 @@ func ParseConfig(hclConfig string) (_ *Config, err error) {
return nil, errors.New("the jwt_issuer url must contain a host")
}
}
if c.JWKSURI != "" {
jwksURI, err := url.Parse(c.JWKSURI)
if err != nil || jwksURI.Scheme == "" || jwksURI.Host == "" {
return nil, fmt.Errorf("the jwks_uri setting could not be parsed: %w", err)
}
}
return c, nil
}

Expand Down
76 changes: 53 additions & 23 deletions support/oidc-discovery-provider/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,40 @@ type Handler struct {
allowInsecureScheme bool
setKeyUse bool
log logrus.FieldLogger
jwtIssuer string
jwtIssuer *url.URL
jwksURI *url.URL
serverPathPrefix string

http.Handler
}

func NewHandler(log logrus.FieldLogger, domainPolicy DomainPolicy, source JWKSSource, allowInsecureScheme bool, setKeyUse bool, jwtIssuer string) *Handler {
func NewHandler(log logrus.FieldLogger, domainPolicy DomainPolicy, source JWKSSource, allowInsecureScheme bool, setKeyUse bool, jwtIssuer *url.URL, jwksURI *url.URL, serverPathPrefix string) *Handler {
if serverPathPrefix == "" {
serverPathPrefix = "/"
}
h := &Handler{
domainPolicy: domainPolicy,
source: source,
allowInsecureScheme: allowInsecureScheme,
setKeyUse: setKeyUse,
log: log,
jwtIssuer: jwtIssuer,
jwksURI: jwksURI,
serverPathPrefix: serverPathPrefix,
}

mux := http.NewServeMux()
mux.Handle("/.well-known/openid-configuration", handlers.ProxyHeaders(http.HandlerFunc(h.serveWellKnown)))
mux.Handle("/keys", http.HandlerFunc(h.serveKeys))
wkPath, err := url.JoinPath(serverPathPrefix, "/.well-known/openid-configuration")
if err != nil {
return nil
}
jwksPath, err := url.JoinPath(serverPathPrefix, "/keys")
if err != nil {
return nil
}

mux.Handle(wkPath, handlers.ProxyHeaders(http.HandlerFunc(h.serveWellKnown)))
mux.Handle(jwksPath, http.HandlerFunc(h.serveKeys))

h.Handler = mux
return h
Expand All @@ -53,35 +69,49 @@ func (h *Handler) serveWellKnown(w http.ResponseWriter, r *http.Request) {
return
}

var host string
var path string
var urlScheme string
if h.jwtIssuer != "" {
jwtIssuerURL, _ := url.Parse(h.jwtIssuer)
host = jwtIssuerURL.Host
path = jwtIssuerURL.Path
urlScheme = jwtIssuerURL.Scheme
var issuerURL *url.URL
if h.jwtIssuer != nil {
issuerURL = &url.URL{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to sanitize the URL? Wondering if there is a reason not to set issuerURL directly to h.jwtIssuer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Just evolutionary cruft I think... it was patched and moved around so much it just ended up this way. I'll collapse it.

Scheme: h.jwtIssuer.Scheme,
Host: h.jwtIssuer.Host,
Path: h.jwtIssuer.Path,
}
} else {
host = r.Host
urlScheme = "https"
urlScheme := "https"
if h.allowInsecureScheme && r.TLS == nil && r.URL.Scheme != "https" {
urlScheme = "http"
}
issuerURL = &url.URL{
Scheme: urlScheme,
Host: r.Host,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we include serverPathPrefix in the Issuer here?
Per the specs:

OpenID Providers supporting Discovery MUST make a JSON document available at the path formed by concatenating the string /.well-known/openid-configuration to the Issuer.

So technically, if the well-known document includes a path component, the issuer should too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends on if there are any proxies doing rewrites in front...

But, yeah. I think your probably right, as the default, if the serverPathPrefix is set, the default may benefit from having it set too. The user can always override issuer if they are using a proxy in front.

}
}

if err := h.verifyHost(host); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
var jwksURI *url.URL
if h.jwksURI != nil {
jwksURI = h.jwksURI
} else {
tmpURLScheme := "https"
if h.allowInsecureScheme && r.TLS == nil && r.URL.Scheme != "https" {
tmpURLScheme = "http"
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is common to the two so we could move it outside of the two ifs (for issuer and jwks urls).

keysPath, err := url.JoinPath(h.serverPathPrefix, "keys")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
jwksURI = &url.URL{
Scheme: tmpURLScheme,
Host: r.Host,
Path: keysPath,
}
}
sorindumitru marked this conversation as resolved.
Show resolved Hide resolved

issuerURL := url.URL{
Scheme: urlScheme,
Host: host,
Path: path,
if err := h.verifyHost(r.Host); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

jwksURI := issuerURL.JoinPath("keys")

doc := struct {
Issuer string `json:"issuer"`
JWKSURI string `json:"jwks_uri"`
Expand Down
Loading
Loading