mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-06 10:21:05 +02:00
authorize: preserve original context (#2247)
This commit is contained in:
parent
96d6005639
commit
12c8bb2da4
4 changed files with 63 additions and 1 deletions
|
@ -11,6 +11,7 @@ import (
|
||||||
"gopkg.in/square/go-jose.v2"
|
"gopkg.in/square/go-jose.v2"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
|
@ -139,6 +140,8 @@ func (e *Evaluator) Evaluate(ctx context.Context, req *Request) (*Result, error)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
carryOverJWTAssertion(headersOutput.Headers, req.HTTP.Headers)
|
||||||
|
|
||||||
res := &Result{
|
res := &Result{
|
||||||
Allow: policyOutput.Allow,
|
Allow: policyOutput.Allow,
|
||||||
Deny: policyOutput.Deny,
|
Deny: policyOutput.Deny,
|
||||||
|
@ -227,3 +230,18 @@ func safeEval(ctx context.Context, q rego.PreparedEvalQuery, options ...rego.Eva
|
||||||
resultSet, err = q.Eval(ctx, options...)
|
resultSet, err = q.Eval(ctx, options...)
|
||||||
return resultSet, err
|
return resultSet, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// carryOverJWTAssertion copies assertion JWT from request to response
|
||||||
|
// note that src keys are expected to be http.CanonicalHeaderKey
|
||||||
|
func carryOverJWTAssertion(dst http.Header, src map[string]string) {
|
||||||
|
jwtForKey := http.CanonicalHeaderKey(httputil.HeaderPomeriumJWTAssertionFor)
|
||||||
|
jwtFor, ok := src[jwtForKey]
|
||||||
|
if ok && jwtFor != "" {
|
||||||
|
dst.Add(jwtForKey, jwtFor)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
jwtFor, ok = src[http.CanonicalHeaderKey(httputil.HeaderPomeriumJWTAssertion)]
|
||||||
|
if ok && jwtFor != "" {
|
||||||
|
dst.Add(jwtForKey, jwtFor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ import (
|
||||||
"gopkg.in/square/go-jose.v2"
|
"gopkg.in/square/go-jose.v2"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||||
"github.com/pomerium/pomerium/pkg/grpc/directory"
|
"github.com/pomerium/pomerium/pkg/grpc/directory"
|
||||||
|
@ -453,6 +455,46 @@ func TestEvaluator(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.True(t, res.Allow)
|
assert.True(t, res.Allow)
|
||||||
})
|
})
|
||||||
|
t.Run("carry over assertion header", func(t *testing.T) {
|
||||||
|
tcs := []struct {
|
||||||
|
src map[string]string
|
||||||
|
jwtAssertionFor string
|
||||||
|
}{
|
||||||
|
{map[string]string{}, ""},
|
||||||
|
{map[string]string{
|
||||||
|
http.CanonicalHeaderKey(httputil.HeaderPomeriumJWTAssertion): "identity-a",
|
||||||
|
}, "identity-a"},
|
||||||
|
{map[string]string{
|
||||||
|
http.CanonicalHeaderKey(httputil.HeaderPomeriumJWTAssertionFor): "identity-a",
|
||||||
|
http.CanonicalHeaderKey(httputil.HeaderPomeriumJWTAssertion): "identity-b",
|
||||||
|
}, "identity-a"},
|
||||||
|
}
|
||||||
|
for _, tc := range tcs {
|
||||||
|
res, err := eval(t, options, []proto.Message{
|
||||||
|
&session.Session{
|
||||||
|
Id: "session1",
|
||||||
|
UserId: "user1",
|
||||||
|
},
|
||||||
|
&user.User{
|
||||||
|
Id: "user1",
|
||||||
|
},
|
||||||
|
}, &Request{
|
||||||
|
Policy: &policies[8],
|
||||||
|
Session: RequestSession{
|
||||||
|
ID: "session1",
|
||||||
|
},
|
||||||
|
HTTP: RequestHTTP{
|
||||||
|
Method: "GET",
|
||||||
|
URL: "https://from.example.com",
|
||||||
|
ClientCertificate: testValidCert,
|
||||||
|
Headers: tc.src,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if assert.NoError(t, err) {
|
||||||
|
assert.Equal(t, tc.jwtAssertionFor, res.Headers.Get(httputil.HeaderPomeriumJWTAssertionFor))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustParseURL(str string) *url.URL {
|
func mustParseURL(str string) *url.URL {
|
||||||
|
|
|
@ -478,7 +478,7 @@ func mkRouteMatch(policy *config.Policy) *envoy_config_route_v3.RouteMatch {
|
||||||
func getRequestHeadersToRemove(options *config.Options, policy *config.Policy) []string {
|
func getRequestHeadersToRemove(options *config.Options, policy *config.Policy) []string {
|
||||||
requestHeadersToRemove := policy.RemoveRequestHeaders
|
requestHeadersToRemove := policy.RemoveRequestHeaders
|
||||||
if !policy.PassIdentityHeaders {
|
if !policy.PassIdentityHeaders {
|
||||||
requestHeadersToRemove = append(requestHeadersToRemove, httputil.HeaderPomeriumJWTAssertion)
|
requestHeadersToRemove = append(requestHeadersToRemove, httputil.HeaderPomeriumJWTAssertion, httputil.HeaderPomeriumJWTAssertionFor)
|
||||||
for _, claim := range options.JWTClaimsHeaders {
|
for _, claim := range options.JWTClaimsHeaders {
|
||||||
requestHeadersToRemove = append(requestHeadersToRemove, httputil.PomeriumJWTHeaderName(claim))
|
requestHeadersToRemove = append(requestHeadersToRemove, httputil.PomeriumJWTHeaderName(claim))
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ const (
|
||||||
HeaderPomeriumResponse = "x-pomerium-intercepted-response"
|
HeaderPomeriumResponse = "x-pomerium-intercepted-response"
|
||||||
// HeaderPomeriumJWTAssertion is the header key containing JWT signed user details.
|
// HeaderPomeriumJWTAssertion is the header key containing JWT signed user details.
|
||||||
HeaderPomeriumJWTAssertion = "x-pomerium-jwt-assertion"
|
HeaderPomeriumJWTAssertion = "x-pomerium-jwt-assertion"
|
||||||
|
// HeaderPomeriumJWTAssertionFor carries over original user identity from a chain of network calls.
|
||||||
|
HeaderPomeriumJWTAssertionFor = "x-pomerium-jwt-assertion-for"
|
||||||
// HeaderPomeriumReproxyPolicy is the header key containing the policy to reproxy a request to.
|
// HeaderPomeriumReproxyPolicy is the header key containing the policy to reproxy a request to.
|
||||||
HeaderPomeriumReproxyPolicy = "x-pomerium-reproxy-policy"
|
HeaderPomeriumReproxyPolicy = "x-pomerium-reproxy-policy"
|
||||||
// HeaderPomeriumReproxyPolicyHMAC is an HMAC of the HeaderPomeriumReproxyPolicy header.
|
// HeaderPomeriumReproxyPolicyHMAC is an HMAC of the HeaderPomeriumReproxyPolicy header.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue