Skip to content

Commit 148bb41

Browse files
authored
Merge pull request #1355 from hejfelix/feature/aad-mfa-token
pass mfa-token in AzureAD provider
2 parents 36ab9ae + cd7b0c3 commit 148bb41

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

pkg/provider/aad/aad.go

+10-6
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ AuthProcessor:
191191
res, err = ac.processKmsiInterrupt(res, resBodyStr)
192192
case strings.Contains(resBodyStr, "ConvergedTFA"):
193193
logger.Debug("processing ConvergedTFA")
194-
res, err = ac.processConvergedTFA(res, resBodyStr)
194+
res, err = ac.processConvergedTFA(res, resBodyStr, loginDetails)
195195
case strings.Contains(resBodyStr, "SAMLRequest"):
196196
logger.Debug("processing SAMLRequest")
197197
res, err = ac.processSAMLRequest(res, resBodyStr)
@@ -407,7 +407,7 @@ func (ac *Client) processKmsiInterrupt(res *http.Response, srcBodyStr string) (*
407407
return res, nil
408408
}
409409

410-
func (ac *Client) processConvergedTFA(res *http.Response, srcBodyStr string) (*http.Response, error) {
410+
func (ac *Client) processConvergedTFA(res *http.Response, srcBodyStr string, loginDetails *creds.LoginDetails) (*http.Response, error) {
411411
var convergedResponse *ConvergedResponse
412412
var err error
413413

@@ -425,7 +425,7 @@ func (ac *Client) processConvergedTFA(res *http.Response, srcBodyStr string) (*h
425425
}
426426
} else if len(mfas) != 0 {
427427
// there's no explicit option to skip MFA, and MFA options are available
428-
res, err = ac.processMfa(mfas, convergedResponse)
428+
res, err = ac.processMfa(mfas, convergedResponse, loginDetails)
429429
if err != nil {
430430
return res, err
431431
}
@@ -434,7 +434,7 @@ func (ac *Client) processConvergedTFA(res *http.Response, srcBodyStr string) (*h
434434
return res, nil
435435
}
436436

437-
func (ac *Client) processMfa(mfas []userProof, convergedResponse *ConvergedResponse) (*http.Response, error) {
437+
func (ac *Client) processMfa(mfas []userProof, convergedResponse *ConvergedResponse, loginDetails *creds.LoginDetails) (*http.Response, error) {
438438
var res *http.Response
439439
var err error
440440
var mfaResp mfaResponse
@@ -457,8 +457,12 @@ func (ac *Client) processMfa(mfas []userProof, convergedResponse *ConvergedRespo
457457
SessionID: mfaResp.SessionID,
458458
}
459459
if mfaReq.AuthMethodID == "PhoneAppOTP" || mfaReq.AuthMethodID == "OneWaySMS" {
460-
verifyCode := prompter.StringRequired("Enter verification code")
461-
mfaReq.AdditionalAuthData = verifyCode
460+
if loginDetails.MFAToken != "" {
461+
mfaReq.AdditionalAuthData = loginDetails.MFAToken
462+
} else {
463+
verifyCode := prompter.StringRequired("Enter verification code")
464+
mfaReq.AdditionalAuthData = verifyCode
465+
}
462466
}
463467
if mfaReq.AuthMethodID == "PhoneAppNotification" && i == 0 {
464468
if mfaResp.Entropy == 0 {

pkg/provider/aad/aad_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,52 @@ func Test_Authenticate(t *testing.T) {
316316
require.Nil(t, err)
317317
require.NotEmpty(t, got)
318318
})
319+
t.Run("Pass mfa-token via loginDetails", func(t *testing.T) {
320+
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
321+
switch r.URL.Path {
322+
case "/index", "/applications/redirecttofederatedapplication.aspx":
323+
writeFixtureBytes(t, w, r, "ConvergedSignIn.html", FixtureData{
324+
UrlPost: "/defaultLogin",
325+
UrlGetCredentialType: "/getCredentialType",
326+
})
327+
case "/getCredentialType":
328+
writeFixtureBytes(t, w, r, "GetCredentialType_default.json", FixtureData{})
329+
case "/defaultLogin":
330+
writeFixtureBytes(t, w, r, "KmsiInterrupt.html", FixtureData{
331+
UrlPost: "/hForm",
332+
})
333+
case "/hForm":
334+
writeFixtureBytes(t, w, r, "HiddenForm.html", FixtureData{
335+
UrlHiddenForm: "/sRequest",
336+
})
337+
case "/sRequest":
338+
writeFixtureBytes(t, w, r, "SAMLRequest.html", FixtureData{
339+
UrlSamlRequest: "/sResponse?SAMLRequest=ExampleValue",
340+
})
341+
case "/sResponse":
342+
writeFixtureBytes(t, w, r, "ConvergedTFA.html", FixtureData{
343+
UrlPost: "/processAuth",
344+
UrlBeginAuth: "/beginAuth",
345+
UrlEndAuth: "/endAuth",
346+
})
347+
case "/beginAuth":
348+
writeFixtureBytes(t, w, r, "BeginAuth.json", FixtureData{})
349+
case "/endAuth":
350+
writeFixtureBytes(t, w, r, "EndAuth.json", FixtureData{})
351+
case "/processAuth":
352+
writeFixtureBytes(t, w, r, "SAMLResponse.html", FixtureData{})
353+
default:
354+
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
355+
}
356+
}))
357+
defer ts.Close()
358+
359+
ac, loginDetails := setupTestClient(t, ts)
360+
loginDetails.MFAToken = "000000"
361+
got, err := ac.Authenticate(loginDetails)
362+
require.Nil(t, err)
363+
require.NotEmpty(t, got)
364+
})
319365
t.Run("Default login with KMSI and MFA but Authenticator required", func(t *testing.T) {
320366
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
321367
switch r.URL.Path {

0 commit comments

Comments
 (0)