Skip to content

Commit

Permalink
Add oauth2_metadata config option
Browse files Browse the repository at this point in the history
Signed-off-by: Dave Dykstra <2129743+DrDaveD@users.noreply.github.com>
  • Loading branch information
DrDaveD committed May 10, 2024
1 parent cf73343 commit bf835da
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 1 deletion.
20 changes: 20 additions & 0 deletions builtin/credential/jwt/path_oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,23 @@ func (b *jwtAuthBackend) pathCallback(ctx context.Context, req *logical.Request,
}
}

// Also fetch any requested extra oauth2 metadata
oauth2Metadata := make(map[string]string)
for _, mdname := range role.Oauth2Metadata {
var md string
switch mdname {
case "id_token":
md = string(token.IDToken())
case "refresh_token":
md = string(token.RefreshToken())
case "access_token":
md = string(token.AccessToken())
default:
return logical.ErrorResponse(errLoginFailed + " Unrecognized oauth2 metadata name " + mdname), nil
}
oauth2Metadata[mdname] = md
}

if role.VerboseOIDCLogging {
if c, err := json.Marshal(allClaims); err == nil {
b.Logger().Debug("OIDC provider response", "claims", string(c))
Expand All @@ -331,6 +348,9 @@ func (b *jwtAuthBackend) pathCallback(ctx context.Context, req *logical.Request,
for k, v := range alias.Metadata {
tokenMetadata[k] = v
}
for k, v := range oauth2Metadata {
tokenMetadata["oauth2_"+k] = v
}

auth := &logical.Auth{
Policies: role.Policies,
Expand Down
11 changes: 10 additions & 1 deletion builtin/credential/jwt/path_oidc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,16 @@ func TestOIDC_Callback(t *testing.T) {

auth := resp.Auth

if auth != nil {
// Can't predict the content of oauth2_id_token
// so instead copy it. This does at least
// verify that it is present because if not it
// introduces an empty value into expected.
expected.Metadata["oauth2_id_token"] = auth.Metadata["oauth2_id_token"]
}

if !reflect.DeepEqual(auth, expected) {
t.Fatalf("expected: %v, auth: %v", expected, resp)
t.Fatalf("expected: %v, resp: %v", expected, resp)
}
}
})
Expand Down Expand Up @@ -1587,6 +1595,7 @@ func getBackendAndServer(t *testing.T, boundCIDRs bool) (logical.Backend, logica
"/nested/secret_code": "bar",
"temperature": "76",
},
"oauth2_metadata": []string{"id_token"},
}

if boundCIDRs {
Expand Down
10 changes: 10 additions & 0 deletions builtin/credential/jwt/path_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ Defaults to 60 (1 minute) if set to 0 and can be disabled if set to -1.`,
Type: framework.TypeKVPairs,
Description: `Mappings of claims (key) that will be copied to a metadata field (value)`,
},
"oauth2_metadata": {
Type: framework.TypeCommaStringSlice,
Description: `Comma-separated list of one or more of access_token, id_token, refresh_token to return in metadata`,
},
"user_claim": {
Type: framework.TypeString,
Description: `The claim to use for the Identity entity alias name`,
Expand Down Expand Up @@ -231,6 +235,7 @@ type jwtRole struct {
BoundClaimsType string `json:"bound_claims_type"`
BoundClaims map[string]interface{} `json:"bound_claims"`
ClaimMappings map[string]string `json:"claim_mappings"`
Oauth2Metadata []string `json:"oauth2_metadata"`
UserClaim string `json:"user_claim"`
GroupsClaim string `json:"groups_claim"`
OIDCScopes []string `json:"oidc_scopes"`
Expand Down Expand Up @@ -346,6 +351,7 @@ func (b *jwtAuthBackend) pathRoleRead(ctx context.Context, req *logical.Request,
"bound_claims_type": role.BoundClaimsType,
"bound_claims": role.BoundClaims,
"claim_mappings": role.ClaimMappings,
"oauth2_metadata": role.Oauth2Metadata,
"user_claim": role.UserClaim,
"user_claim_json_pointer": role.UserClaimJSONPointer,
"groups_claim": role.GroupsClaim,
Expand Down Expand Up @@ -538,6 +544,10 @@ func (b *jwtAuthBackend) pathRoleCreateUpdate(ctx context.Context, req *logical.
role.ClaimMappings = claimMappings
}

if oauth2Metadata, ok := data.GetOk("oauth2_metadata"); ok {
role.Oauth2Metadata = oauth2Metadata.([]string)
}

if userClaim, ok := data.GetOk("user_claim"); ok {
role.UserClaim = userClaim.(string)
}
Expand Down
1 change: 1 addition & 0 deletions builtin/credential/jwt/path_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ func TestPath_Read(t *testing.T) {
"bound_claims_type": "string",
"bound_claims": map[string]interface{}(nil),
"claim_mappings": map[string]string(nil),
"oauth2_metadata": []string(nil),
"bound_subject": "testsub",
"bound_audiences": []string{"vault"},
"allowed_redirect_uris": []string{"http://127.0.0.1"},
Expand Down
3 changes: 3 additions & 0 deletions changelog/320.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:feature
auth/oidc: Add a new `oauth2_metadata` configuration option to enable sending any of the tokens from the token issuer to the client.
```

0 comments on commit bf835da

Please sign in to comment.