Forum Discussion

David_E__Smith_'s avatar
David_E__Smith_
Icon for Nimbostratus rankNimbostratus
Jan 10, 2017

Trouble implementing multi-stage authentication (AD + Duo)

I'm trying to implement an unusual multi-stage, multi-factor authentication process, and I'm getting hung up for reasons that aren't clear to me.

 

Here's the existing, and working, system: The user actually authenticates to another system (legacy stuff), then the F5 gets the username and password handed back via HTTP parameters. APM populates session.logon.last.username and .password from this info via iRule and APM Variable Assign. I show the user a blank login page, that has embedded JavaScript; that JS prompts the user to complete Duo's multi-factor auth process. Assuming this is done successfully, the session is established and the user can use our application.

 

(There's more to it, including iRules that completely disable all of the above for certain on-site IP addresses, but those are the important bits.)

 

Here's what that looks like in the APM:

 

(Ignore the "IP Check Macro" in the above; it's not used. The IP checks are now done via iRule, checking an IP list datagroup.)

 

I've been asked to try to add another step, before presenting the Duo login screen. One of the systems this policy protects is our HR system, and former employees may need to access their tax forms from years past, update contact info, and so on. We don't want to make someone that is no longer affiliated with us, jump through a bunch of extra hoops for a one-off. So, we want to do an AD group check, to see if the user is an active employee. That check is simple enough, by itself. Here's what that all looks like, on a different F5 APM:

 

 

If I remove the "AD Group Check Macro" from the main APM flow, everything works perfectly. This is what I'd expect, because everything is identical. Similarly, if the user logging in is NOT a member of a group where the multi-factor check is required, everything works (because nothing happens, and the user is sent straight to an "Allow" terminator).

 

But if the user is a member of the groups I'm checking for in the AD Query, the whole thing seems to hang. The session log shows that I hit the "Need Duo" end of the macro, but it doesn't proceed past there. The browser appears hung on a "/my.policy" page; the source of that page is AFAICT identical to the source of the page when the macro isn't even in play. (Since it's the same "Logon Page" element, this of course makes sense.)

 

I'm kinda stumped here. All the values should be completely identical, but when I do a seemingly-unrelated AD query before showing the logon page, the logon page no longer works. Any ideas, or even suggestions on how better to trouble-shoot this?

 

6 Replies

  • Could you send the screenshot of AD Auth and the code of "Rest LP from iRule" ?

     

  • Hi,

    In your VPE, the AD Auth does not have any logon page before to get username and password.

    Another point, why are you using irule events in VPE? it is better to use ACCESS_SESSION_STARTED event and write a session variable, then evaluate this variable in VPE.

    when ACCESS_SESSION_STARTED {
        if { [class match [IP::client_addr] equals SINGLE_AUTH_DG] } {
            ACCESS::session data set session.custom.single_auth_allowed_ip 1 
        } else {
            ACCESS::session data set session.custom.single_auth_allowed_ip 0
        }
        if { [class match [IP::client_addr] equals DUO_AUTH_DG] } {
            ACCESS::session data set session.custom.duo_auth_allowed_ip 1 
        } else {
            ACCESS::session data set session.custom.duo_auth_allowed_ip 0
        }
    }
    
  • As requested, though I'm not sure this is the right place to look:

     

     

     

    We have iRules that trigger on HTTP_REQUEST and HTTP_REQUEST_DATA, to collect the username and password from the HTTP payload, and store them in a table. Then, on ACCESS_SESSION_STARTED, I pull that data back out of the table and pop it into the session.custom.username and session.custom.password fields with the VPE action. (I don't remember if it was impossible to populate session.logon.last.x directly, or if it was just considered poor practice to do so.)

     

    The AD auth is just a simple auth -- since the user has already been authenticated to our application, I don't need to do this. It's just simpler to do an auth, followed by a query, than to do a query with a service account.

     

  • I do not understand why you need to assign custom.username and password to logon.last.x parameters. They can be just used in AD auth as is. After hitting "Need Duo", What is the error on my.policy page? Could you share the screenshot?

     

  • So at the start of the policy the session.custom.* variables are already set? In your first example you have a Logon Page before anything happens, but not in the updated example.

     

    I'd add a bunch of logging agents to your VPE at various points, and dump the session variables to the log. It might be that one of them is not set as expected. The message box agent works well here too, in a development scenario.

     

    On the other hand, I don't understand the difficulty in setting up a service account to operate your AD Query. It could save you a big headache, and works well in our environment. Did you run into specific issues with that?

     

  • The username and password are set by an iRule (before the user enters this access policy, the credentials are pulled from other HTTP POST headers). The credentials are provided before the start of the access policy, so I cannot set them directly in my iRule. I have to store them in custom session parameters, then use the first VPE action (a Variable Assign) to copy the custom parameters into the standard place.

     

    The /my.policy page, in the second scenario (AD, then Duo) is just a blank page. Viewing the source of the page, it's identical to that of the login page in the first (Duo-only) scenario, but for some reason the Duo JavaScript isn't running. I'm wondering if it's some really arcane client-side issue, honestly.