From 600028fdd645806c737f25339de79e87eb8f6ae9 Mon Sep 17 00:00:00 2001 From: Henning Perl Date: Tue, 28 Jan 2025 13:46:01 +0100 Subject: [PATCH] add netid token claim support --- embedx/config.schema.json | 6 +++ .../strategy/oidc/fedcm/definitions.go | 3 ++ selfservice/strategy/oidc/provider_config.go | 4 ++ selfservice/strategy/oidc/provider_netid.go | 38 ++++++++++++++++--- .../strategy/oidc/provider_netid_test.go | 29 ++++++++++++++ 5 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 selfservice/strategy/oidc/provider_netid_test.go diff --git a/embedx/config.schema.json b/embedx/config.schema.json index ad4db74df0e9..049de330a512 100644 --- a/embedx/config.schema.json +++ b/embedx/config.schema.json @@ -586,6 +586,12 @@ "type": "string", "format": "uri", "examples": ["https://example.com/config.json"] + }, + "net_id_token_origin_header": { + "title": "NetID Token Origin Header", + "description": "Contains the orgin header to be used when exchanging a NetID FedCM token for an ID token", + "type": "string", + "examples": ["https://example.com"] } }, "additionalProperties": false, diff --git a/selfservice/strategy/oidc/fedcm/definitions.go b/selfservice/strategy/oidc/fedcm/definitions.go index a21c14a7b0eb..f72a6e676d9e 100644 --- a/selfservice/strategy/oidc/fedcm/definitions.go +++ b/selfservice/strategy/oidc/fedcm/definitions.go @@ -85,6 +85,9 @@ type SubmitFedcmTokenBody struct { } // swagger:parameters submitFedcmToken +// +//nolint:deadcode,unused +//lint:ignore U1000 Used to generate Swagger and OpenAPI definitions type submitFedcmToken struct { // in: body // required: true diff --git a/selfservice/strategy/oidc/provider_config.go b/selfservice/strategy/oidc/provider_config.go index e27dd6db25fc..c9de47e3d799 100644 --- a/selfservice/strategy/oidc/provider_config.go +++ b/selfservice/strategy/oidc/provider_config.go @@ -132,6 +132,10 @@ type Configuration struct { // FedCMConfigURL is the URL to the FedCM IdP configuration file. // This is only effective in the Ory Network. FedCMConfigURL string `json:"fedcm_config_url"` + + // NetIDTokenOriginHeader contains the orgin header to be used when exchanging a + // NetID FedCM token for an ID token. + NetIDTokenOriginHeader string `json:"net_id_token_origin_header"` } func (p Configuration) Redir(public *url.URL) string { diff --git a/selfservice/strategy/oidc/provider_netid.go b/selfservice/strategy/oidc/provider_netid.go index 93e3f3532cea..5bbab1931e92 100644 --- a/selfservice/strategy/oidc/provider_netid.go +++ b/selfservice/strategy/oidc/provider_netid.go @@ -4,12 +4,14 @@ package oidc import ( + "bytes" "context" "encoding/json" "fmt" + "io" "net/url" "slices" - "testing" + "strings" "github.com/coreos/go-oidc/v3/oidc" "github.com/hashicorp/go-retryablehttp" @@ -123,13 +125,37 @@ func (n *ProviderNetID) Verify(ctx context.Context, rawIDToken string) (*Claims, return nil, err } + req, err := retryablehttp.NewRequestWithContext(ctx, "POST", urlx.AppendPaths(n.brokerURL(), "/token").String(), strings.NewReader(url.Values{ + "grant_type": {"netid_fedcm"}, + "fedcm_token": {rawIDToken}, + }.Encode())) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("Origin", n.config.NetIDTokenOriginHeader) + res, err := n.reg.HTTPClient(ctx).Do(req) + if err != nil { + return nil, err + } + + token := struct { + IDToken string `json:"id_token"` + }{} + + body, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + + if err := json.NewDecoder(bytes.NewBuffer(body)).Decode(&token); err != nil { + return nil, err + } + idToken, err := provider.VerifierContext( n.withHTTPClientContext(ctx), - &oidc.Config{ - ClientID: n.config.ClientID, - InsecureSkipSignatureCheck: testing.Testing(), - }, - ).Verify(ctx, rawIDToken) + &oidc.Config{ClientID: n.config.ClientID}, + ).Verify(ctx, token.IDToken) if err != nil { return nil, err } diff --git a/selfservice/strategy/oidc/provider_netid_test.go b/selfservice/strategy/oidc/provider_netid_test.go new file mode 100644 index 000000000000..759bc663acbe --- /dev/null +++ b/selfservice/strategy/oidc/provider_netid_test.go @@ -0,0 +1,29 @@ +// Copyright © 2023 Ory Corp +// SPDX-License-Identifier: Apache-2.0 + +package oidc_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ory/kratos/internal" + "github.com/ory/kratos/selfservice/strategy/oidc" +) + +func TestNetidProvider(t *testing.T) { + t.Skip("can't test this automatically, because the token is only valid for a short time") + _, reg := internal.NewVeryFastRegistryWithoutDB(t) + + p := oidc.NewProviderNetID(&oidc.Configuration{ + ClientID: "9b56b26a-e93d-4fce-8f16-951a9858f23e", + }, reg) + + rawToken := `...` + + claims, err := p.(oidc.IDTokenVerifier).Verify(context.Background(), rawToken) + require.NoError(t, err) + require.NotNil(t, claims) +}