mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-02 16:30:17 +02:00
controlplane: move jwks.json endpoint to control plane (#3691)
This commit is contained in:
parent
63b210e51d
commit
b68dc1ff4f
6 changed files with 99 additions and 70 deletions
|
@ -2,15 +2,14 @@
|
|||
package controlplane
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/CAFxX/httpcompression"
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/pomerium/csrf"
|
||||
"github.com/pomerium/pomerium/config"
|
||||
"github.com/pomerium/pomerium/internal/httputil"
|
||||
"github.com/pomerium/pomerium/internal/log"
|
||||
|
@ -47,32 +46,23 @@ func (srv *Server) addHTTPMiddleware(root *mux.Router, cfg *config.Config) {
|
|||
root.Use(telemetry.HTTPStatsHandler(func() string {
|
||||
return srv.currentConfig.Load().Options.InstallationID
|
||||
}, srv.name))
|
||||
root.HandleFunc("/healthz", httputil.HealthCheck)
|
||||
root.HandleFunc("/ping", httputil.HealthCheck)
|
||||
root.Handle("/.well-known/pomerium", httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||
return wellKnownPomerium(w, r, cfg)
|
||||
}))
|
||||
root.Handle("/.well-known/pomerium/", httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||
return wellKnownPomerium(w, r, cfg)
|
||||
}))
|
||||
}
|
||||
|
||||
func wellKnownPomerium(w http.ResponseWriter, r *http.Request, cfg *config.Config) error {
|
||||
func (srv *Server) mountCommonEndpoints(root *mux.Router, cfg *config.Config) error {
|
||||
authenticateURL, err := cfg.Options.GetAuthenticateURL()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("invalid authenticate URL: %w", err)
|
||||
}
|
||||
|
||||
wellKnownURLs := struct {
|
||||
OAuth2Callback string `json:"authentication_callback_endpoint"` // RFC6749
|
||||
JSONWebKeySetURL string `json:"jwks_uri"` // RFC7517
|
||||
FrontchannelLogoutURI string `json:"frontchannel_logout_uri"` // https://openid.net/specs/openid-connect-frontchannel-1_0.html
|
||||
}{
|
||||
authenticateURL.ResolveReference(&url.URL{Path: "/oauth2/callback"}).String(),
|
||||
authenticateURL.ResolveReference(&url.URL{Path: "/.well-known/pomerium/jwks.json"}).String(),
|
||||
authenticateURL.ResolveReference(&url.URL{Path: "/.pomerium/sign_out"}).String(),
|
||||
rawSigningKey, err := cfg.Options.GetSigningKey()
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid signing key: %w", err)
|
||||
}
|
||||
w.Header().Set("X-CSRF-Token", csrf.Token(r))
|
||||
httputil.RenderJSON(w, http.StatusOK, wellKnownURLs)
|
||||
|
||||
root.HandleFunc("/healthz", httputil.HealthCheck)
|
||||
root.HandleFunc("/ping", httputil.HealthCheck)
|
||||
root.Handle("/.well-known/pomerium", httputil.WellKnownPomeriumHandler(authenticateURL))
|
||||
root.Handle("/.well-known/pomerium/", httputil.WellKnownPomeriumHandler(authenticateURL))
|
||||
root.Path("/.well-known/pomerium/jwks.json").Methods(http.MethodGet).Handler(httputil.JWKSHandler(rawSigningKey))
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -285,6 +285,9 @@ func (srv *Server) EnableProxy(svc Service) error {
|
|||
func (srv *Server) updateRouter(cfg *config.Config) error {
|
||||
httpRouter := mux.NewRouter()
|
||||
srv.addHTTPMiddleware(httpRouter, cfg)
|
||||
if err := srv.mountCommonEndpoints(httpRouter, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
if srv.authenticateSvc != nil {
|
||||
authenticateURL, err := cfg.Options.GetInternalAuthenticateURL()
|
||||
if err != nil {
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
"github.com/pomerium/pomerium/pkg/netutil"
|
||||
)
|
||||
|
||||
func TestServerWellKnown(t *testing.T) {
|
||||
func TestServerHTTP(t *testing.T) {
|
||||
ports, err := netutil.AllocatePorts(5)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -33,23 +33,49 @@ func TestServerWellKnown(t *testing.T) {
|
|||
Options: config.NewDefaultOptions(),
|
||||
}
|
||||
cfg.Options.AuthenticateURLString = "https://authenticate.localhost.pomerium.io"
|
||||
cfg.Options.SigningKey = "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUpCMFZkbko1VjEvbVlpYUlIWHhnd2Q0Yzd5YWRTeXMxb3Y0bzA1b0F3ekdvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFVUc1eENQMEpUVDFINklvbDhqS3VUSVBWTE0wNENnVzlQbEV5cE5SbVdsb29LRVhSOUhUMwpPYnp6aktZaWN6YjArMUt3VjJmTVRFMTh1dy82MXJVQ0JBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo="
|
||||
|
||||
src := config.NewStaticSource(cfg)
|
||||
srv, err := NewServer(cfg, config.NewMetricsManager(ctx, src), events.New())
|
||||
require.NoError(t, err)
|
||||
go srv.Run(ctx)
|
||||
|
||||
res, err := http.Get(fmt.Sprintf("http://localhost:%s/.well-known/pomerium", src.GetConfig().HTTPPort))
|
||||
require.NoError(t, err)
|
||||
defer res.Body.Close()
|
||||
t.Run("well-known", func(t *testing.T) {
|
||||
res, err := http.Get(fmt.Sprintf("http://localhost:%s/.well-known/pomerium", src.GetConfig().HTTPPort))
|
||||
require.NoError(t, err)
|
||||
defer res.Body.Close()
|
||||
|
||||
var actual map[string]any
|
||||
err = json.NewDecoder(res.Body).Decode(&actual)
|
||||
require.NoError(t, err)
|
||||
var actual map[string]any
|
||||
err = json.NewDecoder(res.Body).Decode(&actual)
|
||||
require.NoError(t, err)
|
||||
|
||||
expect := map[string]any{
|
||||
"authentication_callback_endpoint": "https://authenticate.localhost.pomerium.io/oauth2/callback",
|
||||
"frontchannel_logout_uri": "https://authenticate.localhost.pomerium.io/.pomerium/sign_out",
|
||||
"jwks_uri": "https://authenticate.localhost.pomerium.io/.well-known/pomerium/jwks.json",
|
||||
}
|
||||
assert.Equal(t, expect, actual)
|
||||
expect := map[string]any{
|
||||
"authentication_callback_endpoint": "https://authenticate.localhost.pomerium.io/oauth2/callback",
|
||||
"frontchannel_logout_uri": "https://authenticate.localhost.pomerium.io/.pomerium/sign_out",
|
||||
"jwks_uri": "https://authenticate.localhost.pomerium.io/.well-known/pomerium/jwks.json",
|
||||
}
|
||||
assert.Equal(t, expect, actual)
|
||||
})
|
||||
t.Run("jwks", func(t *testing.T) {
|
||||
res, err := http.Get(fmt.Sprintf("http://localhost:%s/.well-known/pomerium/jwks.json", src.GetConfig().HTTPPort))
|
||||
require.NoError(t, err)
|
||||
defer res.Body.Close()
|
||||
|
||||
var actual map[string]any
|
||||
err = json.NewDecoder(res.Body).Decode(&actual)
|
||||
require.NoError(t, err)
|
||||
|
||||
expect := map[string]any{
|
||||
"keys": []any{map[string]any{
|
||||
"alg": "ES256",
|
||||
"crv": "P-256",
|
||||
"kid": "5b419ade1895fec2d2def6cd33b1b9a018df60db231dc5ecb85cbed6d942813c",
|
||||
"kty": "EC",
|
||||
"use": "sig",
|
||||
"x": "UG5xCP0JTT1H6Iol8jKuTIPVLM04CgW9PlEypNRmWlo",
|
||||
"y": "KChF0fR09zm884ymInM29PtSsFdnzExNfLsP-ta1AgQ",
|
||||
}},
|
||||
}
|
||||
assert.Equal(t, expect, actual)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue