Skip to content

Commit

Permalink
working_1
Browse files Browse the repository at this point in the history
  • Loading branch information
matya committed Feb 2, 2024
1 parent cca903f commit 72747a6
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 0 deletions.
7 changes: 7 additions & 0 deletions path_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ func pathConfig(b *jwtAuthBackend) *framework.Path {
Name: "Provider Config",
},
},
"acr_values": {
Type: framework.TypeCommaStringSlice,
Description: "Authentication Context Class Reference values. Optional.",
},
"namespace_in_state": {
Type: framework.TypeBool,
Description: "Pass namespace in the OIDC state parameter instead of as a separate query parameter. With this setting, the allowed redirect URL(s) in Vault and on the provider side should not contain a namespace query parameter. This means only one redirect URL entry needs to be maintained on the provider side for all vault namespaces that will be authenticating against it. Defaults to true for new configs.",
Expand Down Expand Up @@ -204,6 +208,7 @@ func (b *jwtAuthBackend) pathConfigRead(ctx context.Context, req *logical.Reques
"bound_issuer": config.BoundIssuer,
"provider_config": providerConfig,
"namespace_in_state": config.NamespaceInState,
"acr_values": config.ACRValues,
},
}

Expand All @@ -225,6 +230,7 @@ func (b *jwtAuthBackend) pathConfigWrite(ctx context.Context, req *logical.Reque
JWTSupportedAlgs: d.Get("jwt_supported_algs").([]string),
BoundIssuer: d.Get("bound_issuer").(string),
ProviderConfig: d.Get("provider_config").(map[string]interface{}),
ACRValues: d.Get("acr_values").([]string),
}

// Check if the config already exists, to determine if this is a create or
Expand Down Expand Up @@ -417,6 +423,7 @@ type jwtConfig struct {
BoundIssuer string `json:"bound_issuer"`
DefaultRole string `json:"default_role"`
ProviderConfig map[string]interface{} `json:"provider_config"`
ACRValues []string `json:"acr_values"`
NamespaceInState bool `json:"namespace_in_state"`

ParsedJWTPubKeys []crypto.PublicKey `json:"-"`
Expand Down
13 changes: 13 additions & 0 deletions path_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func TestConfig_JWT_Read(t *testing.T) {
"bound_issuer": "http://vault.example.com/",
"provider_config": map[string]interface{}{},
"namespace_in_state": false,
"acr_values": []string{},
}

req := &logical.Request{
Expand Down Expand Up @@ -142,6 +143,7 @@ func TestConfig_JWT_Write(t *testing.T) {
BoundIssuer: "http://vault.example.com/",
ProviderConfig: map[string]interface{}{},
NamespaceInState: true,
ACRValues: []string{},
}

conf, err := b.(*jwtAuthBackend).config(context.Background(), storage)
Expand Down Expand Up @@ -179,6 +181,7 @@ func TestConfig_JWKS_Update(t *testing.T) {
"bound_issuer": "",
"provider_config": map[string]interface{}{},
"namespace_in_state": false,
"acr_values": []string{},
}

req := &logical.Request{
Expand Down Expand Up @@ -354,6 +357,7 @@ func TestConfig_OIDC_Write(t *testing.T) {
OIDCClientSecret: "def",
ProviderConfig: map[string]interface{}{},
NamespaceInState: true,
ACRValues: []string{},
}

conf, err := b.(*jwtAuthBackend).config(context.Background(), storage)
Expand Down Expand Up @@ -446,6 +450,7 @@ func TestConfig_OIDC_Write_ProviderConfig(t *testing.T) {
"extraOptions": "abound",
},
NamespaceInState: true,
ACRValues: []string{},
}

conf, err := b.(*jwtAuthBackend).config(context.Background(), storage)
Expand Down Expand Up @@ -503,6 +508,7 @@ func TestConfig_OIDC_Write_ProviderConfig(t *testing.T) {
OIDCDiscoveryURL: "https://team-vault.auth0.com/",
ProviderConfig: map[string]interface{}{},
NamespaceInState: true,
ACRValues: []string{},
}

conf, err := b.(*jwtAuthBackend).config(context.Background(), storage)
Expand Down Expand Up @@ -533,6 +539,7 @@ func TestConfig_OIDC_Create_Namespace(t *testing.T) {
JWTSupportedAlgs: []string{},
JWTValidationPubKeys: []string{},
ProviderConfig: map[string]interface{}{},
ACRValues: []string{},
},
},
"namespace_in_state true": {
Expand All @@ -547,6 +554,7 @@ func TestConfig_OIDC_Create_Namespace(t *testing.T) {
JWTSupportedAlgs: []string{},
JWTValidationPubKeys: []string{},
ProviderConfig: map[string]interface{}{},
ACRValues: []string{},
},
},
"namespace_in_state false": {
Expand All @@ -561,6 +569,7 @@ func TestConfig_OIDC_Create_Namespace(t *testing.T) {
JWTSupportedAlgs: []string{},
JWTValidationPubKeys: []string{},
ProviderConfig: map[string]interface{}{},
ACRValues: []string{},
},
},
}
Expand Down Expand Up @@ -609,6 +618,7 @@ func TestConfig_OIDC_Update_Namespace(t *testing.T) {
JWTSupportedAlgs: []string{},
JWTValidationPubKeys: []string{},
ProviderConfig: map[string]interface{}{},
ACRValues: []string{},
},
},
"existing false, update something else": {
Expand All @@ -628,6 +638,7 @@ func TestConfig_OIDC_Update_Namespace(t *testing.T) {
JWTSupportedAlgs: []string{},
JWTValidationPubKeys: []string{},
ProviderConfig: map[string]interface{}{},
ACRValues: []string{},
},
},
"existing true, update to false": {
Expand All @@ -646,6 +657,7 @@ func TestConfig_OIDC_Update_Namespace(t *testing.T) {
JWTSupportedAlgs: []string{},
JWTValidationPubKeys: []string{},
ProviderConfig: map[string]interface{}{},
ACRValues: []string{},
},
},
"existing true, update something else": {
Expand All @@ -665,6 +677,7 @@ func TestConfig_OIDC_Update_Namespace(t *testing.T) {
JWTSupportedAlgs: []string{},
JWTValidationPubKeys: []string{},
ProviderConfig: map[string]interface{}{},
ACRValues: []string{},
},
},
}
Expand Down
4 changes: 4 additions & 0 deletions path_oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,10 @@ func (b *jwtAuthBackend) createOIDCRequest(config *jwtConfig, role *jwtRole, rol
options = append(options, oidc.WithMaxAge(uint(role.MaxAge.Seconds())))
}

if len(config.ACRValues) > 0 {
options = append(options, oidc.WithACRValues(strings.Join(config.ACRValues[:], " ")))
}

request, err := oidc.NewRequest(oidcRequestTimeout, redirectURI, options...)
if err != nil {
return nil, err
Expand Down
91 changes: 91 additions & 0 deletions path_oidc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1638,3 +1638,94 @@ func TestParseMount(t *testing.T) {
t.Fatalf("unexpected result: %s", result)
}
}

// The acr_values parameter refers to authentication context class reference.
// Examples taken from:
// https://developer.okta.com/docs/guides/step-up-authentication/main/#predefined-parameter-values

func TestOIDC_AuthURL_acr_values(t *testing.T) {
b, storage := getBackend(t)

tests := map[string]struct {
acr_values []string
expectedAcrValue string
shouldExist bool
}{
"auth URL for acr_values of urn:okta:loa:1fa:any": {
acr_values: []string{"urn:okta:loa:1fa:any"},
expectedAcrValue: "urn:okta:loa:1fa:any",
shouldExist: true,
},
"auth URL for acr_values of phrh": {
acr_values: []string{"phrh"},
expectedAcrValue: "phrh",
shouldExist: true,
},
"auth URL for acr_values of urn:okta:loa:1fa:any and phrh": {
acr_values: []string{"urn:okta:loa:1fa:any", "phrh"},
expectedAcrValue: "urn:okta:loa:1fa:any phrh",
shouldExist: true,
},
"auth URL for empty acr_values": {
acr_values: []string{},
shouldExist: false,
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {

// Configure the backend
req := &logical.Request{
Operation: logical.UpdateOperation,
Path: configPath,
Storage: storage,
Data: map[string]interface{}{
"oidc_discovery_url": "https://team-vault.auth0.com/",
"oidc_client_id": "abc",
"oidc_client_secret": "def",
"acr_values": tt.acr_values,
},
}
resp, err := b.HandleRequest(context.Background(), req)
require.NoError(t, err)
require.False(t, resp.IsError())

req = &logical.Request{
Operation: logical.CreateOperation,
Path: "role/test",
Storage: storage,
Data: map[string]interface{}{
"user_claim": "email",
"allowed_redirect_uris": []string{"https://example.com"},
},
}
resp, err = b.HandleRequest(context.Background(), req)
require.NoError(t, err)
require.False(t, resp.IsError())

// Request for generation of an auth URL
req = &logical.Request{
Operation: logical.UpdateOperation,
Path: "oidc/auth_url",
Storage: storage,
Data: map[string]interface{}{
"role": "test",
"redirect_uri": "https://example.com",
},
}
resp, err = b.HandleRequest(context.Background(), req)
require.NoError(t, err)
require.False(t, resp.IsError())

// Parse the auth URL and assert the expected acr_values query parameter
parsedAuthURL, err := url.Parse(resp.Data["auth_url"].(string))
require.NoError(t, err)
queryParams := parsedAuthURL.Query()
if tt.shouldExist {
assert.Equal(t, tt.expectedAcrValue, queryParams.Get("acr_values"))
} else {
assert.Empty(t, queryParams.Get("acr_values"))
}
})
}
}

0 comments on commit 72747a6

Please sign in to comment.