Skip to content
Open
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
4 changes: 4 additions & 0 deletions caddyfile_adapt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ func TestCaddyfileAdaptAuthenticationToJSON(t *testing.T) {
name: "authenticate plugin config with registration",
inputFileNamePrefix: "testcase_authenticate_with_registration",
},
{
name: "authenticate plugin config with auth challenges",
inputFileNamePrefix: "testcase_authenticate_with_auth_challenges",
},
{
name: "security app config with authentication portal with static secrets manager plugin",
inputFileNamePrefix: "testcase_security_with_secrets",
Expand Down
9 changes: 9 additions & 0 deletions caddyfile_identity_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ func parseCaddyfileIdentityStore(d *caddyfile.Dispenser, cfg *authcrunch.Config,
username := args[0]
userMap["username"] = username
apiKeyList := []map[string]interface{}{}
authChallengeRules := []string{}
for userNesting := d.Nesting(); d.NextBlock(userNesting); {
userPropName := d.Val()
userPropValue := d.RemainingArgs()
Expand Down Expand Up @@ -186,6 +187,11 @@ func parseCaddyfileIdentityStore(d *caddyfile.Dispenser, cfg *authcrunch.Config,
return errors.ErrMalformedDirectiveValue.WithArgs(rd, args, userPropName+" must contain one or more value")
}
userMap[userPropName] = userPropValue
case "auth":
if len(userPropValue) < 2 || userPropValue[0] != "challenges" {
return errors.ErrMalformedDirectiveValue.WithArgs(rd, args, userPropName+" must be followed by challenges")
}
authChallengeRules = append(authChallengeRules, strings.Join(userPropValue[1:], " "))
case "api":
if len(userPropValue) != 3 {
return errors.ErrMalformedDirectiveValue.WithArgs(rd, args, userPropName+" key must contain two values")
Expand All @@ -204,6 +210,9 @@ func parseCaddyfileIdentityStore(d *caddyfile.Dispenser, cfg *authcrunch.Config,
if len(apiKeyList) > 0 {
userMap["api_keys"] = apiKeyList
}
if len(authChallengeRules) > 0 {
userMap["auth_challenge_rules"] = authChallengeRules
}
userMaps = append(userMaps, userMap)
case "groups":
// LDAP only.
Expand Down
86 changes: 86 additions & 0 deletions caddyfile_identity_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,92 @@ func TestParseCaddyfileIdentityStore(t *testing.T) {
}
}`,
},
{
name: "test local identity store with auth challenge rules",
d: caddyfile.NewTestDispenser(`
security {
local identity store localdb {
realm local
path /tmp/localdb
user jsmith {
name John Smith
email jsmith@localdomain.local
password "My@Password123"
roles authp/user
auth challenges u2f
auth challenges password totp if u2f not available
auth challenges password if u2f and totp not available
}
}
authentication portal myportal {
enable identity store localdb
}
}`),
want: `{
"config": {
"authentication_portals": [
{
"name": "myportal",
"ui": {},
"cookie_config": {
"session_id_cookie_name": "AUTHP_SESSION_ID",
"referer_cookie_name": "AUTHP_REDIRECT_URL",
"sandbox_id_cookie_name": "AUTHP_SANDBOX_ID",
"identity_token_cookie_name": "AUTHP_ID_TOKEN",
"access_token_cookie_name": "AUTHP_ACCESS_TOKEN",
"refresh_token_cookie_name": "AUTHP_REFRESH_TOKEN",
"cookie_name_prefix": "AUTHP"
},
"crypto_key_store_config": {
"auto_generate_algo": "ES512",
"auto_generate_tag": "default"
},
"identity_stores": [
"localdb"
],
"portal_admin_roles": {
"authp/admin": true
},
"portal_user_roles": {
"authp/user": true
},
"portal_guest_roles": {
"authp/guest": true
},
"api": {
"profile_enabled": true
},
"token_validator_options": {},
"token_grantor_options": {}
}
],
"identity_stores": [
{
"name": "localdb",
"kind": "local",
"params": {
"path": "/tmp/localdb",
"realm": "local",
"users": [
{
"username": "jsmith",
"name": "John Smith",
"email_address": "jsmith@localdomain.local",
"password": "My@Password123",
"roles": ["authp/user"],
"auth_challenge_rules": [
"u2f",
"password totp if u2f not available",
"password if u2f and totp not available"
]
}
]
}
}
]
}
}`,
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions caddyfile_resolve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ func TestResolveRuntimeAppConfig(t *testing.T) {
name: "authenticate plugin config with ui",
inputFileNamePrefix: "testcase_authenticate_with_ui",
},
{
name: "authenticate plugin config with auth challenges",
inputFileNamePrefix: "testcase_authenticate_with_auth_challenges",
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
security {
local identity store localdb {
realm local
path assets/config/users.json
user jsmith {
name John Smith
email jsmith@localdomain.local
password "My@Password123"
roles authp/user
auth challenges u2f
auth challenges password totp if u2f not available
auth challenges password if u2f and totp not available
}
}

authentication portal myportal {
crypto key sign-verify {env.JWT_SHARED_KEY}
enable identity store localdb
}
}
}

:443 {
authenticate with myportal
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JWT_SHARED_KEY=testkey123
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"handle": [
{
"handler": "authenticator",
"portal_name": "myportal",
"route_matcher": "*"
}
]
}
]
}
}
},
"security": {
"config": {
"authentication_portals": [
{
"name": "myportal",
"ui": {},
"cookie_config": {
"session_id_cookie_name": "AUTHP_SESSION_ID",
"referer_cookie_name": "AUTHP_REDIRECT_URL",
"sandbox_id_cookie_name": "AUTHP_SANDBOX_ID",
"identity_token_cookie_name": "AUTHP_ID_TOKEN",
"access_token_cookie_name": "AUTHP_ACCESS_TOKEN",
"refresh_token_cookie_name": "AUTHP_REFRESH_TOKEN",
"cookie_name_prefix": "AUTHP"
},
"identity_stores": [
"localdb"
],
"token_validator_options": {},
"raw_crypto_key_store_config": [
"crypto key sign-verify {env.JWT_SHARED_KEY}"
],
"crypto_key_store_config": {
"raw_key_configs": [
"crypto key sign-verify {env.JWT_SHARED_KEY}"
],
"auto_generate_tag": "default",
"auto_generate_algo": "ES512"
},
"token_grantor_options": {},
"portal_admin_roles": {
"authp/admin": true
},
"portal_user_roles": {
"authp/user": true
},
"portal_guest_roles": {
"authp/guest": true
},
"api": {
"profile_enabled": true
}
}
],
"identity_stores": [
{
"name": "localdb",
"kind": "local",
"params": {
"path": "assets/config/users.json",
"realm": "local",
"users": [
{
"auth_challenge_rules": [
"u2f",
"password totp if u2f not available",
"password if u2f and totp not available"
],
"email_address": "jsmith@localdomain.local",
"name": "John Smith",
"password": "My@Password123",
"roles": [
"authp/user"
],
"username": "jsmith"
}
]
}
}
]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"authentication_portals": [
{
"name": "myportal",
"ui": {},
"cookie_config": {
"session_id_cookie_name": "AUTHP_SESSION_ID",
"referer_cookie_name": "AUTHP_REDIRECT_URL",
"sandbox_id_cookie_name": "AUTHP_SANDBOX_ID",
"identity_token_cookie_name": "AUTHP_ID_TOKEN",
"access_token_cookie_name": "AUTHP_ACCESS_TOKEN",
"refresh_token_cookie_name": "AUTHP_REFRESH_TOKEN",
"cookie_name_prefix": "AUTHP"
},
"identity_stores": [
"localdb"
],
"token_validator_options": {},
"raw_crypto_key_store_config": [
"crypto key sign-verify testkey123"
],
"crypto_key_store_config": {
"raw_key_configs": [
"crypto key sign-verify testkey123"
],
"auto_generate_tag": "default",
"auto_generate_algo": "ES512"
},
"token_grantor_options": {},
"portal_admin_roles": {
"authp/admin": true
},
"portal_user_roles": {
"authp/user": true
},
"portal_guest_roles": {
"authp/guest": true
},
"api": {
"profile_enabled": true
}
}
],
"identity_stores": [
{
"name": "localdb",
"kind": "local",
"params": {
"path": "assets/config/users.json",
"realm": "local",
"users": [
{
"auth_challenge_rules": [
"u2f",
"password totp if u2f not available",
"password if u2f and totp not available"
],
"email_address": "jsmith@localdomain.local",
"name": "John Smith",
"password": "My@Password123",
"roles": [
"authp/user"
],
"username": "jsmith"
}
]
}
}
]
}
Loading