add security token header support

Signed-off-by: yaron2 <schneider.yaron@live.com>
This commit is contained in:
yaron2 2023-01-25 15:03:43 -08:00
parent 570f67b797
commit 1a653144bf
3 changed files with 66 additions and 9 deletions

View File

@ -45,6 +45,8 @@ const (
TraceparentHeaderKey = "traceparent"
TracestateHeaderKey = "tracestate"
TraceMetadataKey = "traceHeaders"
securityToken = "securityToken"
securityTokenHeader = "securityTokenHeader"
)
// HTTPSource is a binding for an http url endpoint invocation
@ -58,10 +60,12 @@ type HTTPSource struct {
}
type httpMetadata struct {
URL string `mapstructure:"url"`
MTLSClientCert string `mapstructure:"mtlsClientCert"`
MTLSClientKey string `mapstructure:"mtlsClientKey"`
MTLSRootCA string `mapstructure:"mtlsRootCA"`
URL string `mapstructure:"url"`
MTLSClientCert string `mapstructure:"mtlsClientCert"`
MTLSClientKey string `mapstructure:"mtlsClientKey"`
MTLSRootCA string `mapstructure:"mtlsRootCA"`
SecurityToken string `mapstructure:"securityToken"`
SecurityTokenHeader string `mapstructure:"securityTokenHeader"`
}
// NewHTTP returns a new HTTPSource.
@ -233,6 +237,11 @@ func (h *HTTPSource) Invoke(ctx context.Context, req *bindings.InvokeRequest) (*
request.Header.Set("Accept", "application/json; charset=utf-8")
}
// Set security token values if set.
if h.metadata.SecurityToken != "" && h.metadata.SecurityTokenHeader != "" {
request.Header.Set(h.metadata.SecurityTokenHeader, h.metadata.SecurityToken)
}
// Any metadata keys that start with a capital letter
// are treated as request headers
for mdKey, mdValue := range req.Metadata {

View File

@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package http_test
package http
import (
"context"
@ -31,13 +31,12 @@ import (
"github.com/stretchr/testify/require"
"github.com/dapr/components-contrib/bindings"
bindingHttp "github.com/dapr/components-contrib/bindings/http"
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/kit/logger"
)
func TestOperations(t *testing.T) {
opers := (*bindingHttp.HTTPSource)(nil).Operations()
opers := (*HTTPSource)(nil).Operations()
assert.Equal(t, []bindings.OperationKind{
bindings.CreateOperation,
"get",
@ -132,7 +131,7 @@ func InitBinding(s *httptest.Server, extraProps map[string]string) (bindings.Out
}
}
hs := bindingHttp.NewHTTP(logger.NewLogger("test"))
hs := NewHTTP(logger.NewLogger("test"))
err := hs.Init(m)
return hs, err
}
@ -166,6 +165,44 @@ func TestNon2XXErrorsSuppressed(t *testing.T) {
verifyNon2XXErrorsSuppressed(t, hs, handler)
}
func TestSecurityTokenHeaderForwarded(t *testing.T) {
handler := NewHTTPHandler()
s := httptest.NewServer(handler)
defer s.Close()
t.Run("security token headers are forwarded", func(t *testing.T) {
hs, err := InitBinding(s, map[string]string{securityTokenHeader: "X-Token", securityToken: "12345"})
require.NoError(t, err)
req := TestCase{
input: "GET",
operation: "get",
path: "/",
err: "",
statusCode: 200,
}.ToInvokeRequest()
_, err = hs.Invoke(context.Background(), &req)
assert.NoError(t, err)
assert.Equal(t, "12345", handler.Headers["X-Token"])
})
t.Run("security token headers are forwarded", func(t *testing.T) {
hs, err := InitBinding(s, nil)
require.NoError(t, err)
req := TestCase{
input: "GET",
operation: "get",
path: "/",
err: "",
statusCode: 200,
}.ToInvokeRequest()
_, err = hs.Invoke(context.Background(), &req)
assert.NoError(t, err)
assert.Empty(t, handler.Headers["X-Token"])
})
}
func TestTraceHeadersForwarded(t *testing.T) {
handler := NewHTTPHandler()
s := httptest.NewServer(handler)
@ -231,7 +268,7 @@ func InitBindingForHTTPS(s *httptest.Server, extraProps map[string]string) (bind
for k, v := range extraProps {
m.Properties[k] = v
}
hs := bindingHttp.NewHTTP(logger.NewLogger("test"))
hs := NewHTTP(logger.NewLogger("test"))
err := hs.Init(m)
return hs, err
}

View File

@ -54,3 +54,14 @@ metadata:
description: "The client certificate key to present to server to enable client verification"
binding:
output: true
- name: securityToken
required: false
description: "The security token to include on an outgoing HTTP request as a header"
binding:
output: true
- name: securityTokenHeader
required: false
description: "The header name on an outgoing HTTP request for a security token"
binding:
output: true