mirror of
https://github.com/pomerium/pomerium.git
synced 2025-07-27 13:39:04 +02:00
jwt: require logged in user to return .pomerium/jwt (#3809)
jwt: require logged in user to return .pomerium/jwt (#3807) * jwt: require logged in user to return .pomerium/jwt * fix test * update test Co-authored-by: Caleb Doxsey <cdoxsey@pomerium.com>
This commit is contained in:
parent
ebee7c7920
commit
0b3d4f3a6f
4 changed files with 24 additions and 5 deletions
|
@ -59,6 +59,7 @@ default deny = [false, set()]
|
||||||
|
|
||||||
pomerium_routes_0 = [true, {"pomerium-route"}] {
|
pomerium_routes_0 = [true, {"pomerium-route"}] {
|
||||||
contains(input.http.url, "/.pomerium/")
|
contains(input.http.url, "/.pomerium/")
|
||||||
|
not contains(input.http.url, "/.pomerium/jwt")
|
||||||
}
|
}
|
||||||
|
|
||||||
else = [false, {"non-pomerium-route"}] {
|
else = [false, {"non-pomerium-route"}] {
|
||||||
|
|
|
@ -11,6 +11,9 @@ var pomeriumRoutesBody = ast.Body{
|
||||||
ast.MustParseExpr(`
|
ast.MustParseExpr(`
|
||||||
contains(input.http.url, "/.pomerium/")
|
contains(input.http.url, "/.pomerium/")
|
||||||
`),
|
`),
|
||||||
|
ast.MustParseExpr(`
|
||||||
|
not contains(input.http.url, "/.pomerium/jwt")
|
||||||
|
`),
|
||||||
}
|
}
|
||||||
|
|
||||||
type pomeriumRoutesCriterion struct {
|
type pomeriumRoutesCriterion struct {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/go-jose/go-jose/v3/jwt"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
|
@ -178,12 +179,25 @@ func (p *Proxy) ProgrammaticLogin(w http.ResponseWriter, r *http.Request) error
|
||||||
|
|
||||||
// jwtAssertion returns the current request's JWT assertion (rfc7519#section-10.3.1).
|
// jwtAssertion returns the current request's JWT assertion (rfc7519#section-10.3.1).
|
||||||
func (p *Proxy) jwtAssertion(w http.ResponseWriter, r *http.Request) error {
|
func (p *Proxy) jwtAssertion(w http.ResponseWriter, r *http.Request) error {
|
||||||
assertionJWT := r.Header.Get(httputil.HeaderPomeriumJWTAssertion)
|
rawAssertionJWT := r.Header.Get(httputil.HeaderPomeriumJWTAssertion)
|
||||||
if assertionJWT == "" {
|
if rawAssertionJWT == "" {
|
||||||
return httputil.NewError(http.StatusNotFound, errors.New("jwt not found"))
|
return httputil.NewError(http.StatusNotFound, errors.New("jwt not found"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assertionJWT, err := jwt.ParseSigned(rawAssertionJWT)
|
||||||
|
if err != nil {
|
||||||
|
return httputil.NewError(http.StatusNotFound, errors.New("jwt not found"))
|
||||||
|
}
|
||||||
|
|
||||||
|
var dst struct {
|
||||||
|
Subject string `json:"sub"`
|
||||||
|
}
|
||||||
|
if assertionJWT.UnsafeClaimsWithoutVerification(&dst) != nil || dst.Subject == "" {
|
||||||
|
return httputil.NewError(http.StatusUnauthorized, errors.New("jwt not found"))
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/jwt")
|
w.Header().Set("Content-Type", "application/jwt")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
_, _ = io.WriteString(w, assertionJWT)
|
_, _ = io.WriteString(w, rawAssertionJWT)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -547,13 +547,14 @@ func TestProxy_jwt(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// with upstream request headers being set
|
// with upstream request headers being set
|
||||||
|
rawJWT := "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTY3MDg4OTI0MSwiZXhwIjoxNjcwODkyODQxfQ.YoROB12_-a8VxikPqrYOA576pLYoLFeGwXAOWCGpXgM"
|
||||||
req, _ = http.NewRequest("GET", "https://www.example.com/.pomerium/jwt", nil)
|
req, _ = http.NewRequest("GET", "https://www.example.com/.pomerium/jwt", nil)
|
||||||
w = httptest.NewRecorder()
|
w = httptest.NewRecorder()
|
||||||
req.Header.Set(httputil.HeaderPomeriumJWTAssertion, "MOCK_JWT")
|
req.Header.Set(httputil.HeaderPomeriumJWTAssertion, rawJWT)
|
||||||
err = proxy.jwtAssertion(w, req)
|
err = proxy.jwtAssertion(w, req)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert.Equal(t, "application/jwt", w.Header().Get("Content-Type"))
|
assert.Equal(t, "application/jwt", w.Header().Get("Content-Type"))
|
||||||
assert.Equal(t, w.Body.String(), "MOCK_JWT")
|
assert.Equal(t, w.Body.String(), rawJWT)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue