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

feat: client_credentials authentication strategy for Endpoint enhanced to support the same options as the corresponding finalizer #971

Merged
merged 14 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 19 additions & 7 deletions docs/content/docs/configuration/reference/reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ rules:
config:
identity_info_endpoint:
url: http://127.0.0.1:4433/sessions/whoami
auth:
auth:
type: basic_auth
config:
user: foo
password: bar
retry:
max_delay: 300ms
give_up_after: 2s
Expand All @@ -175,10 +181,11 @@ rules:
max_delay: 300ms
give_up_after: 2s
auth:
type: basic_auth
type: api_key
config:
user: foo
password: bar
in: header
name: X-Api-Key
value: VerySecret!
token_source:
- header: Authorization
schema: Bearer
Expand Down Expand Up @@ -266,11 +273,16 @@ rules:
headers:
bla: bla
auth:
type: api_key
type: client_credentials
config:
in: query
name: key
value: super duper secret
auth_method: request_body
token_url: http://bar.foo
client_id: foo
client_secret: bar
cache_ttl: 20s
header:
name: X-Foo
scheme: Bar
payload: http://foo
- id: profile_data_contextualizer
type: generic
Expand Down
35 changes: 29 additions & 6 deletions docs/content/docs/configuration/reference/types.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -339,39 +339,62 @@ config:
----
====

=== Client Credentials Strategy
=== OAuth2 Client Credentials Grant Flow Strategy

This strategy implements the https://datatracker.ietf.org/doc/html/rfc6749#section-4.4[OAuth2 Client Credentials Grant Flow] to obtain an access token expected by the endpoint. Heimdall caches the received access token.

`type` must be set to `client_credentials`. `config` supports the following properties:


* *`token_url`*: _string_ (mandatory)
+
The token endpoint of the authorization server.

* *`client_id`*: _string_ (mandatory)
+
The client identifier for Heimdall.
The client identifier for heimdall.

* *`client_secret`*: _string_ (mandatory)
+
The client secret for Heimdall.
The client secret for heimdall.

* *`auth_method`*: _string_ (optional)
+
The authentication method to be used according to https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1[RFC 6749, Client Password]. Can be one of

** `basic_auth` (default if `auth_method` is not set): With that authentication method, the `"application/x-www-form-urlencoded"` encoded values of `client_id` and `client_secret` are sent to the authorization server via the `Authorization` header using the `Basic` scheme.

** `request_body`: With that authentication method the `client_id` and `client_secret` are sent in the request body together with the other parameters (e.g. `scopes`) defined by the flow.
+
WARNING: Usage of `request_body` authentication method is not recommended and should be avoided.

* *`scopes`*: _string array_ (optional)
+
The scopes required for the access token.

* *`token_url`*: _string_ (mandatory)
* *`cache_ttl`*: _link:{{< relref "/docs/configuration/reference/types.adoc#_duration" >}}[Duration]_ (optional)
+
The token endpoint of the authorization server.
How long to cache the token received from the token endpoint. Defaults to the token expiration information from the token endpoint (the value of the `expires_in` field) if present. If the token expiration inforation is not present and `cache_ttl` is not configured, the received token is not cached. If the token expiration information is present in the response and `cache_ttl` is configured the shorter value is taken. If caching is enabled, the token is cached until 5 seconds before its expiration. To disable caching, set it to `0s`. The cache key calculation is based on the values of `token_url`, `client_id`, `client_secret` and the `scopes` properties.

* *`header`*: _object_ (optional, overridable)
+
Defines the `name` and `scheme` to be used for the header. Defaults to `Authorization` with scheme `Bearer`. If defined, the `name` property must be set. If `scheme` is not defined, no scheme will be prepended to the resulting JWT.


.Client Credentials Strategy configuration
.Strategy configuration
====

[source, yaml]
----
type: client_credentials
config:
header:
name: X-My-Token
token_url: https://my-auth.provider/token
client_id: foo
client_secret: bar
auth_method: basic_auth
ttl: 10m
scopes:
- baz
- zap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ The client secret for heimdall.

* *`auth_method`*: _string_ (optional, not overridable)
+
The authentication method to be used according to https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1[RFC 6749, Client Password]. Can one of
The authentication method to be used according to https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1[RFC 6749, Client Password]. Can be one of

** `basic_auth` (default if `auth_method` is not set): With that authentication method, the `"application/x-www-form-urlencoded"` encoded values of `client_id` and `client_secret` are sent to the authorization server via the `Authorization` header using the `Basic` scheme.

Expand Down
17 changes: 17 additions & 0 deletions internal/config/test_data/test_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ rules:
config:
endpoint:
url: http://keto/{{ .Values.key }}
auth:
type: api_key
config:
in: header
name: X-Api-Key
value: VerySecret!
method: POST
headers:
foo-bar: "{{ .Subject.ID }}"
Expand All @@ -309,6 +315,17 @@ rules:
config:
endpoint:
url: http://foo.bar
auth:
type: client_credentials
config:
auth_method: request_body
token_url: http://foo.bar
client_id: foo
client_secret: bar
cache_ttl: 20s
header:
name: X-Foo
scheme: Bar
method: GET
headers:
bla: bla
Expand Down
2 changes: 2 additions & 0 deletions internal/rules/endpoint/authentication_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"net/http"
)

//go:generate mockery --name AuthenticationStrategy --structname AuthenticationStrategyMock

type AuthenticationStrategy interface {
Apply(context.Context, *http.Request) error
Hash() []byte
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//
// SPDX-License-Identifier: Apache-2.0

package endpoint
package authstrategy

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//
// SPDX-License-Identifier: Apache-2.0

package endpoint
package authstrategy

import (
"context"
Expand All @@ -24,14 +24,16 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/dadrus/heimdall/internal/rules/endpoint"
)

func TestApplyApiKeyStrategy(t *testing.T) {
t.Parallel()

for _, tc := range []struct {
uc string
strategy AuthenticationStrategy
strategy endpoint.AuthenticationStrategy
assert func(t *testing.T, err error, req *http.Request)
}{
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//
// SPDX-License-Identifier: Apache-2.0

package endpoint
package authstrategy

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//
// SPDX-License-Identifier: Apache-2.0

package endpoint
package authstrategy

import (
"context"
Expand Down
Loading
Loading