jeremyschulman / netbox-plugin-auth-saml2

Netbox plugin for SSO using SAML2
119 stars 21 forks source link

'NoneType' object has no attribute 'text' #41

Closed pk-man closed 2 years ago

pk-man commented 3 years ago

After spending a long time trying to debug this I have decided to make an issue.

I have set up this plugin and the django3-auth-saml2 plugin and am getting this error when I git /api/plugins/sso/acs after successful Okta authentication (checked in Okta logging): {"error": "'NoneType' object has no attribute 'text'", "exception": "AttributeError", "netbox_version": "2.10.3", "python_version": "3.9.6"}

My configuration looks like so (gets translated to python from yaml):

plugins: [
  "django3_saml2_nbplugin"
]

# Remote authentication support
REMOTE_AUTH_ENABLED: true
REMOTE_AUTH_BACKEND: 'netbox.authentication.RemoteUserBackend'
REMOTE_AUTH_HEADER: 'HTTP_REMOTE_USER'
REMOTE_AUTH_AUTO_CREATE_USER: true
REMOTE_AUTH_DEFAULT_GROUPS: []
REMOTE_AUTH_DEFAULT_PERMISSIONS: {}

pluginsConfig:
  django3_saml2_nbplugin:
    AUTHENTICATION_BACKEND: REMOTE_AUTH_BACKEND
    ASSERTION_URL: 'https://netbox-<snip>net/'
    ENTITY_ID: 'https://netbox-<snip>net/'
    METADATA_AUTO_CONF_URL: 'https://<snip>.okta.com/app/<snip>'

Has any one else run into this issue? Thanks in advance.

jeremyschulman commented 3 years ago

Hi @pk-man - all good. I actually ran into the same issue! So I know this one :-)

Your ENTITY_ID and NETADDR_AUTO_CONF_URL values need to be actual/real https addresses. For example, if your netbox server has a FQDN of "netbox.mycompany.net' then these values would be "https://netbox.mycompany.net".

Your example above has "-" from the example, so I am guessing you might have used these values directly without replacing them with your actual netbox URL.

Hope that helps!

pk-man commented 3 years ago

Hey @jeremyschulman thank you for your quick response I'm extremely thankful so that's the actual domain name. It's actually netbox-dev.mycompany.net. I removed identify information as hence why it seems to be fake. I double checked my configuration to make sure that it's not misspelled and that it's a FQDN.

jeremyschulman commented 2 years ago

@pk-man - I believe it is OK to close this issue. If you are still having a problem I can reopen. Thank you!

liquidninja07 commented 2 years ago

After recently working with this plugin, I ran into the same issue when trying to authenticate with OneLogin. I don't know if this is PR worthy, but wanted to give insight in case others have the same issue.

This is the traceback error with debug logging level:

Internal Server Error: /api/plugins/sso/acs/
Traceback (most recent call last):
  File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/netbox/venv/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/opt/netbox/venv/lib/python3.8/site-packages/django3_auth_saml2/views.py", line 105, in sso_acs
    user_name = authn_response.name_id.text
AttributeError: 'NoneType' object has no attribute 'text'

I modified the /opt/netbox/venv/lib/python3.8/site-packages/django3_auth_saml2/views.py file in django3_auth_saml2 plugin and added authn_response.parse_assertion() before line 105. After adding that line, SSO is now working as expected.

...
    authn_response.parse_assertion()

    user_name = authn_response.name_id.text
    backend_name = SAML2_AUTH_CONFIG['AUTHENTICATION_BACKEND']
    backend_obj = load_backend(backend_name)
...

Environment Versions

Netbox Version: 3.1.6
Python Version: 3.8.12

Settings for SSO in configuration.py

# Remote authentication support
REMOTE_AUTH_ENABLED = True
REMOTE_AUTH_BACKEND = 'django3_saml2_nbplugin.backends.SAML2AttrUserBackend'
REMOTE_AUTH_HEADER = 'HTTP_REMOTE_USER'
REMOTE_AUTH_AUTO_CREATE_USER = True
REMOTE_AUTH_DEFAULT_GROUPS = []
REMOTE_AUTH_DEFAULT_PERMISSIONS = {}

# Enable installed plugins. Add the name of each plugin to the list.
PLUGINS = ['django3_saml2_nbplugin']

# Plugins configuration settings. These settings are used by various plugins that the user may have installed.
# Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings.
PLUGINS_CONFIG = {
    'django3_saml2_nbplugin': {
        # Use different Name ID format
        'NAME_ID_FORMAT': 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',

        # Use the Netbox default remote backend
        'AUTHENTICATION_BACKEND': REMOTE_AUTH_BACKEND,

        # Custom URL to validate incoming SAML requests against
        'ASSERTION_URL': 'https://netbox-dev.<removed>.net',

        # Populates the Issuer element in authn reques e.g defined as "Audience URI (SP Entity ID)" in SSO
        'ENTITY_ID': 'https://netbox-dev.<removed>.net',

        # Metadata is required, choose either remote url
        'METADATA_AUTO_CONF_URL': 'https://<removed>.onelogin.com/<removed>',

    }
}
jeremyschulman commented 2 years ago

@liquidninja07 - thank you very much for putting in the effort on this resolution. Yes, please do submit a pull-request and I'll spin a new release.

liquidninja07 commented 2 years ago

Hi @jeremyschulman I submitted a PR on your primary library, django3-auth-saml2 - Parse Attr PR , that should resolve issues in this repo.

jeremyschulman commented 2 years ago

I have uploaded v0.3.0 of django3-auth-saml2 that includes @liquidninja07 fix.