Awx: Allow configurable requestedAuthnContext to allow two-factor authentication in SAML

Created on 8 Sep 2017  路  5Comments  路  Source: ansible/awx

Summary

I have a client that requires two-factor authentication. This is one of the features that the SAML service provides. However, Ansible Tower (AWX) (and, more specifically, the OneLogin SAML authentication library) defaults to setting the "AuthnContext" to "PasswordProtectedTransport" (password authentication). It is required for that variable to not be enforced. Two-factor authentication cannot be used and there is no way to override this in the AWX GUI or CLI.

A temporary workaround is to edit this file [ /var/lib/awx/venv/tower/lib/python2.7/site-packages/onelogin/saml2/settings.py ] and set the "requestedAuthnContext" variable equal to False (changed from True).

self.__security.setdefault('requestedAuthnContext', False)

By disabling this, the SAML service can then correctly enforce two-factor authentication.

The correct way to override this variable is to use a "settings.json" file as shown in this source file:

https://github.com/onelogin/python-saml/blob/v2.2.3/src/onelogin/saml2/settings.py#L227

The override file should contain at least this to ensure SAML two-factor authentication can work (after "flipping a switch" in the GUI or CLI to enable two-factor auth for SAML):

{
    "security": {
        "requestedAuthnContext": false
    }
}

It would be ideal for AWX to create and manage this configuration file.

Environment

  • Ansible Tower version: 3.1.4
  • Ansible version: 2.3.2.0
  • Operating System: RHEL 7.4
  • Web Browser: Firefox and Chrome

Steps To Reproduce:

Setup a SAML server to use for authentication into AWX. Then attempt to force two-factor authentication. It will not work as only passwords are a valid authentication mechanism for SAML currently.

Expected Results:

SAML should support two-factor authentication in AWX.

Actual Results:

SAML can only be used for "one-factor" password authentication in AWX.

Additional Information:

This unrelated issue illustrates a real-world example of what a more complete settings.json file should look like for the OneLogin's SAML Python library:

https://github.com/onelogin/python-saml/issues/101

A completed settings.json should not be required.

api low enhancement

Most helpful comment

@ekultails I've found a less invasive way to achieve this result.

/etc/tower/conf.d/saml.py root:awx owner

SOCIAL_AUTH_SAML_SECURITY_CONFIG = {
    'requestedAuthnContext': False
}

I've verified by introspecting the SAML request sent by the SP (Tower). I'm not sure how to have my SAML service (One Login) provide/require a 2-factor (token) auth. I've made One Login require users to use google auth OTP token. However, One Login doesn't seem to care that the SP sent a PasswordProtectedTransport or an "I don't care" auth requirement.

SP generated SAML request when requestedAuthnContext = True

...
    <samlp:RequestedAuthnContext 
        Comparison="exact">
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
    </samlp:RequestedAuthnContext>

SP generated SAML request when requestedAuthnContext = False does NOT contain the block.
<samlp:RequestedAuthnContext Comparison="exact"></samlp:RequestedAuthnContext> This is good, this is behavior we want.

All 5 comments

I can look at this later today or tomorrow probably.

This workaround works perfectly for the web UI's login page. A SAML button appears on the front page that can be selected and then the client is taken to their external two-factor authentication page.

One problem we did find is that this does not seem to work for directly accessing the API endpoint from a web browser. For example, going to https:://ansible.tower.tld/api/v1/settings/system/ prompts for a username and password. There does not seem to be a way to go through the second authentication factor and I am unsure how this would be accomplished.

Similarly, we've had a request to provide SAML settings such that they can set AuthnRequestsSigned and WantAssertionsSigned to true - I assume this would use the same settings framework.

Yes, those can both be overridden in a settings.json configuration file (that will need to be created).

https://github.com/onelogin/python-saml/blob/v2.2.3/src/onelogin/saml2/settings.py#L271
https://github.com/onelogin/python-saml/blob/v2.2.3/src/onelogin/saml2/settings.py#L278

I assume the configuration file needs to be placed at /var/lib/awx/venv/tower/lib/python2.7/site-packages/onelogin/saml2/settings.json based on this line of code. I could be misinterpreting this, though.

@ekultails I've found a less invasive way to achieve this result.

/etc/tower/conf.d/saml.py root:awx owner

SOCIAL_AUTH_SAML_SECURITY_CONFIG = {
    'requestedAuthnContext': False
}

I've verified by introspecting the SAML request sent by the SP (Tower). I'm not sure how to have my SAML service (One Login) provide/require a 2-factor (token) auth. I've made One Login require users to use google auth OTP token. However, One Login doesn't seem to care that the SP sent a PasswordProtectedTransport or an "I don't care" auth requirement.

SP generated SAML request when requestedAuthnContext = True

...
    <samlp:RequestedAuthnContext 
        Comparison="exact">
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
    </samlp:RequestedAuthnContext>

SP generated SAML request when requestedAuthnContext = False does NOT contain the block.
<samlp:RequestedAuthnContext Comparison="exact"></samlp:RequestedAuthnContext> This is good, this is behavior we want.

Was this page helpful?
0 / 5 - 0 ratings