Require MFA during bootstrap mode

This commit is contained in:
tegwick 2026-05-25 00:09:40 +02:00
parent 56d279a8e6
commit 937cb39de6
5 changed files with 75 additions and 3 deletions

View file

@ -38,6 +38,10 @@ func New(cfg Config, httpClient HTTPClient) *PrivacyIDEAAdapter {
// registered in privacyIDEA. Fails closed: any infrastructure error returns
// (false, err) so callers cannot bypass the check.
func (a *PrivacyIDEAAdapter) CheckMFARequired(ctx context.Context, userID string) (bool, error) {
if a.cfg.RequireForAll {
return true, nil
}
endpoint := strings.TrimRight(a.cfg.BaseURL, "/") + "/token/"
q := url.Values{}

View file

@ -101,6 +101,27 @@ func TestCheckMFARequired_ActiveTokenPresent_ReturnsTrue(t *testing.T) {
}
}
func TestCheckMFARequired_RequireForAll_ReturnsTrueWithoutTokenList(t *testing.T) {
client := &mockHTTPClient{
doFn: func(_ *http.Request) (*http.Response, error) {
t.Fatal("token-list endpoint must not be called when RequireForAll is enabled")
return nil, nil
},
}
cfg := testConfig()
cfg.RequireForAll = true
adapter := privacyidea.New(cfg, client)
required, err := adapter.CheckMFARequired(context.Background(), "alice")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !required {
t.Error("expected MFA required=true when RequireForAll is enabled")
}
}
func TestCheckMFARequired_InactiveTokenOnly_ReturnsFalse(t *testing.T) {
client := &mockHTTPClient{
doFn: func(_ *http.Request) (*http.Response, error) {

View file

@ -8,15 +8,20 @@ import "net/http"
// Config holds all connection parameters for the privacyIDEA adapter.
type Config struct {
// BaseURL is the privacyIDEA server base URL, e.g. "https://privacyidea.local".
BaseURL string
BaseURL string `yaml:"baseURL"`
// AdminToken is the service-account JWT used to authenticate requests to the
// privacyIDEA admin API.
AdminToken string
AdminToken string `yaml:"adminToken"`
// Realm is the privacyIDEA realm to scope token and validate requests.
// Defaults to "netkingdom" when empty.
Realm string
Realm string `yaml:"realm"`
// RequireForAll skips privacyIDEA token-list discovery and requires MFA for
// every authenticated upstream user. This is useful during bootstrap when
// token-list admin credentials may not be durable yet.
RequireForAll bool `yaml:"requireForAll,omitempty"`
}
// realm returns the effective realm, falling back to "netkingdom".