Single Sign On¶
Nautobot supports several different authentication mechanisms including OAuth (1 and 2), OpenID, SAML, and others. To accomplish this, Nautobot comes preinstalled with the social-auth-app-django Python module.
This module supports several authentication backends by default including:
- Microsoft Azure Active Directory
- Okta
- And many more...
Installation¶
Warning
Unless otherwise noted, all remaining steps in this document should all be performed as the nautobot
user!
Hint: Use sudo -iu nautobot
Install Dependencies for OIDC or SAML¶
If you are using OpenID Connect or SAML you will also need to install the extra dependencies for those. These are grouped together under the sso
Python extra for Nautobot and so can be easily installed with a single pip3
command.
Tip
You may find that additional system-level dependencies must be installed first so that the specialized Python libraries for XML can be built and compiled for your system. Specifics will vary by your OS, but for example, on Ubuntu, you may need to run:
Furthermore, due to potential incompatibilities between the precompiled binaries for the lxml
and xmlsec
Python packages that this installation will bring in, you need to tell Pip to not install the precompiled binary for either of these packages. Run the following command as the nautobot
user:
Configuration¶
Authentication Backends¶
To use external authentication, you'll need to define AUTHENTICATION_BACKENDS
in your nautobot_config.py
.
- Insert the desired external authentication backend as the first item in the list. This step is key to properly redirecting when users click the login button.
- You must also ensure that
nautobot.core.authentication.ObjectPermissionBackend
is always the second item in the list. It is an error to exclude this backend.
Note
It is critical that you include the ObjectPermissionsBackend
provided by Nautobot after the desired backend so that object-level permissions features can work properly.
For example, if you wanted to use Google OAuth2 as your authentication backend:
AUTHENTICATION_BACKENDS = [
"social_core.backends.google.GoogleOAuth2",
"nautobot.core.authentication.ObjectPermissionBackend",
]
Note
Many backends have settings specific to that backend that are not covered in this guide. Please consult the documentation for your desired backend linked in the next section.
Warning
You should only enable one social authentication authentication backend. It is technically possible to use multiple backends but we cannot officially support more than one at this time.
Custom Authentication Backends¶
The default external authentication supported is social-auth-app-django as stated above. If you have developed your own external authentication backend, you will need to configure SOCIAL_AUTH_BACKEND_PREFIX
to use your backend instead and correctly enable the SSO redirect when the login button is clicked. For example, if your custom authentication backend is available at custom_auth.backends.custom.Oauth2
, you would set things as follows:
SOCIAL_AUTH_BACKEND_PREFIX = "custom_auth.backends"
AUTHENTICATION_BACKENDS = [
"custom_auth.backends.custom.Oauth2",
"nautobot.core.authentication.ObjectPermissionBackend",
]
In the example above, SOCIAL_AUTH_BACKEND_PREFIX
was set to custom_auth.backends
within the nautobot_config.py
for our custom authentication plugin we created (custom_auth.backends.custom.Oauth2). This will enable the SSO redirect for users when they click the login button.
Select your Authentication Backend¶
You will need to select the correct social authentication module name for your desired method of external authentication. Please see the official Python Social Auth documentation on supported backends for more the full list of backends and any specific configuration or required settings.
Some common backend module names include:
Backend | Social Auth Backend Module Name |
---|---|
Microsoft Azure Active Directory | social_core.backends.azuread.AzureADOAuth2 |
social_core.backends.azuread_b2c.AzureADB2COAuth2 |
|
social_core.backends.azuread_tenant.AzureADTenantOAuth2 |
|
social_core.backends.azuread_tenant.AzureADV2TenantOAuth2 |
|
social_core.backends.gae.GoogleAppEngineAuth |
|
social_core.backends.google.GoogleOAuth2 |
|
social_core.backends.google.GoogleOAuth |
|
social_core.backends.google_openidconnect.GoogleOpenIdConnect |
|
Okta | social_core.backends.okta.OktaOAuth2 |
social_core.backends.okta_openidconnect.OktaOpenIdConnect |
|
SAML | social_core.backends.saml.SAMLAuth |
User Permissions¶
By default, once authenticated, if the user has never logged in before a new user account will be created for the user. This new user will not be a member of any group or have any permissions assigned. If you would like to create users with a default set of permissions there are some additional variables to configure the permissions.
Please see the documentation on EXTERNAL_AUTH_DEFAULT_GROUPS
and EXTERNAL_AUTH_DEFAULT_PERMISSIONS
for more information.
Configuration Guides¶
The following guides are provided for some of the most common authentication methods.
Okta¶
- In the Okta admin portal, create a new Web application
-
Configure the application as follows:
- Base URIs: should be the URI of your Nautobot application such as
https://nautobot.example.com
- Login redirect URIs: should be the Base URI plus
/complete/okta-openidconnect/
such ashttps://nautobot.example.com/complete/okta-openidconnect/
- Logout redirect URIs: should be the Base URI plus
/disconnect/okta-openidconnect/
such ashttps://nautobot.example.com/disconnect/okta-openidconnect/
- Base URIs: should be the URI of your Nautobot application such as
-
Once the application is configured in Okta, SSO can either be configured with OAuth2 or OpenID Connect (OIDC). When using an organization's authentication server OAuth2 is preferred; with custom Okta authentication backends, use OIDC.
Okta - OAuth2¶
Edit your nautobot_config.py
as follows:
AUTHENTICATION_BACKENDS = [
"social_core.backends.okta.OktaOAuth2",
"nautobot.core.authentication.ObjectPermissionBackend",
]
SOCIAL_AUTH_OKTA_OAUTH2_KEY = '<Client ID from Okta>'
SOCIAL_AUTH_OKTA_OAUTH2_SECRET = '<Client Secret From Okta>'
SOCIAL_AUTH_OKTA_OAUTH2_API_URL = 'https://<Okta URL>'
Okta - OpenID¶
Edit your nautobot_config.py
as follows:
AUTHENTICATION_BACKENDS = [
"social_core.backends.okta_openidconnect.OktaOpenIdConnect",
"nautobot.core.authentication.ObjectPermissionBackend",
]
SOCIAL_AUTH_OKTA_OPENIDCONNECT_KEY = '<Client ID from Okta>'
SOCIAL_AUTH_OKTA_OPENIDCONNECT_SECRET = '<Client Secret From Okta>'
SOCIAL_AUTH_OKTA_OPENIDCONNECT_API_URL = 'https://<Okta URL>/oauth2/<Authentication Server>'
The /default
authentication server can be used for testing, however, it should not be used in production.
Okta - SAML¶
See SAML Prerequisites for common setup.
Setup SAML in Okta
- Visit your Okta Admin Dasboard.
- Create a new application (Create App Integration) and select SAML 2.0.
- Give you application a name and logo if you choose.
- Configure the SAML Settings as follows.
- Single Sign-on URL:
https://nautobot.example.com/complete/saml/
- Audience URI:
https://nautobot.example.com
- Default RelayState:
okta
- Name ID Format:
Unspecified
- Application Username:
Okta Username
- Single Sign-on URL:
- Under Attribute Statements, configure the following:
firstName
- Basic -user.firstName
lastName
- Basic -user.lastName
emailAddress
- Basicuser.email
- (Optional) Configure group Attribute statements.
groups
- Basic - Startswith -nautobot
(example, needs to be adjusted to your environment)
- Select
internal application
and thenfinish
. - Don't forget to assign users/groups to the application so they have access.
- Lastly, look at the
Sign On
tab, then Show Details under Metadata details for detail you will need to configure Nautobot.
Edit your nautobot_config.py
as follows:
# Django authentication backends
AUTHENTICATION_BACKENDS = [
"social_core.backends.saml.SAMLAuth",
"nautobot.core.authentication.ObjectPermissionBackend",
]
# The https FQDN to your Nautobot instance
SOCIAL_AUTH_SAML_SP_ENTITY_ID = "https://nautobot.example.com/"
# X.509 cert/key pair used for host verification are not used for this example because
# Nautobot is directly authenticating itself to Google. Set them to empty strings.
SOCIAL_AUTH_SAML_SP_PUBLIC_CERT = ""
SOCIAL_AUTH_SAML_SP_PRIVATE_KEY = ""
# A dictionary that contains information about your app. You must specify values for
# English at a minimum.
SOCIAL_AUTH_SAML_ORG_INFO = {
"en-US": {
"name": "Nautobot",
"displayname": "Nautobot",
"url": "https://nautobot.example.com",
}
}
# Technical point of contact
SOCIAL_AUTH_SAML_TECHNICAL_CONTACT = {
"givenName": "Bob Jones",
"emailAddress": "bob@example.com"
}
# Support point of contact
SOCIAL_AUTH_SAML_SUPPORT_CONTACT = {
"givenName": "Alice Jenkins",
"emailAddress": "alice@example.com"
}
# The Issuer URL for Okta from step 9
OKTA_ENTITY_ID = "<Issuer from Okta>"
# The Sign On URL for Okta from step 9
OKTA_SSO_URL = "<Sign On URL from Okta>"
# The Signing Certificate for Okta from step 9
OKTA_CERTIFICATE = "<Signing Certificate from Okta>"
# The most important setting. List the Entity ID (Issuer), SSO URL (Sign On URL), and x.509 public key certificate
# for each provider that you app wants to support.
SOCIAL_AUTH_SAML_ENABLED_IDPS = {
"okta": {
'force_authn': "true",
'allow_unsolicited': "true",
'requested_authn_context': "false",
"entity_id": OKTA_ENTITY_ID,
"url": OKTA_SSO_URL,
"x509cert": OKTA_CERTIFICATE,
# These are used to map to User object fields in Nautobot using Google
# attribute fields we configured in step 8 of "Setup SAML in Google".
"attr_user_permanent_id": "emailAddress",
"attr_first_name": "firstName",
"attr_last_name": "lastName",
"attr_username": "emailAddress",
"attr_email": "emailAddress",
}
}
# Required for correctly redirecting when behind SSL proxy (NGINX). You may or may not need
# these depending on your production deployment. They are provided here just in case.
SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
Login with Okta SAML¶
Note the provider entry we configured in SOCIAL_AUTH_SAML_ENABLED_IDPS as okta. This will be used to login and will be referenced in the query parameter using idp=okta. For example /login/saml/?idp=okta.
This should be the URL that is mapped to the "Log in" button on the top right of the index page when you navigate to Nautobot in your browser. Clicking this link should automatically redirect you to Google, ask you to "Choose an account", log you in and redirect you back to the Nautobot home page. Your email address will also be your username.
Be sure to configure EXTERNAL_AUTH_DEFAULT_GROUPS and EXTERNAL_AUTH_DEFAULT_PERMISSIONS next.
Okta - Additional Scopes¶
It is possible to get additional OAuth scopes from okta by adding them to the SOCIAL_AUTH_{BACKEND}_SCOPE
list. For example to get the groups
scope from Okta using OAuth2 add the following to your nautobot_config.py
:
for OpenID:
In order to use this returned scope a custom function needs to be written and added to the SOCIAL_AUTH_PIPELINE
as described in the python-social-auth
authentication pipeline documentation.
An example to sync groups with Okta is provided in the examples/okta
folder in the root of the Nautobot repository.
Google - OAuth2¶
The following instructions guide you through the process of configuring Google for OAuth2 authentication.
Important
Please note there is further guidance provided by python-social-auth as well as Google. For more
information please utilize these additional resources.
- In the Google API Console create a new project or select an existing one.
- Select OAuth consent screen from the menu on the left side of the page
- For User Type select Internal and click Create
-
Configure as follows:
- App name: Acme Corp Nautobot
- User support email: select an email
- App logo: The Nautobot logo can be found at
nautobot/project-static/img/nautobot_logo.png
-
Click Save and Continue
- No additional scopes are needed click Save and Continue
- Select Credentials from the menu on the left side of the page
- Click + Create Credentials at the top of the page and select OAuth client ID
-
Configure as follows:
- Application type: Web application
- Name: Nautobot
- Authorized redirect URIs: should be the Nautobot URL plus
/complete/google-oauth2/
for examplehttps://nautobot.example.com/complete/google-oauth2/
-
Click Create
- Edit your
nautobot_config.py
as follows:
AUTHENTICATION_BACKENDS = [
"social_core.backends.google.GoogleOAuth2",
"nautobot.core.authentication.ObjectPermissionBackend",
]
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '<Client ID from Google>'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '<Secret ID from Google>'
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = ['openid']
SAML¶
This guide will walk you through configuring Nautobot to authenticate using SAML with Google as the identity provider.
Important
Please note that there is further guidance provided by python-social-auth and Google. For more information please utilize these additional resources.
Prerequisites¶
Warning
SAML will not work without end-to-end encryption. These requirements are not flexible.
Before you begin you will need the following:
- The fully-qualified domain name (FQDN) of your Nautobot host must be registered in DNS. For this example we will be using
nautobot.example.com
. - A valid publicly trusted SSL certificate matching the FQDN of your host. You cannot use a self-signed certificate. Google validates this certificate to assert authenticity of SAML authentication requests.
- The name and email address for a technical point of contact. For this example we will use
Bob Jones, bob@example.com
. - The name and email address for a support point of contact. For this example we will use
Alice Jenkins, alice@example.com.
Setup SAML in Google¶
- Visit the Web and mobile apps console in the Google Admin dashboard.
- Follow Google's official document to Set up your own custom SAML application, pausing at step 6.
- From step 6 of the instructions, capture the SSO URL, Entity ID, and Certificate. You will use these in later steps to configure Nautobot. Each of these will be referred to as
GOOGLE_SSO_URL
,GOOGLE_ENTITY_ID
, andGOOGLE_CERTIFICATE
respectively. - Skip step 7 in the instructions, as that does not apply here because we will be configuring Nautobot directly.
- For step 9 of the instructions under Service provider details, provide the following
- ACS URL:
https://nautobot.example.com/complete/saml/
- Entity ID:
https://nautobot.example.com/
- Start URL: Leave this field blank
- ACS URL:
- Skip step 10 in the instructions, as a signed response is not required.
- For step 11 of the instructions, under Name ID, set the following:
- Name ID Format: Select EMAIL
- Name ID: Select Basic Information > Primary Email
- For step 13 of the instructions, on the Attribute mapping page, add the following mappings for Google Directory attributes to App attributes:
- Primary email -->
email
- First name -->
first_name
- Last name -->
last_name
- Primary email -->
- Click Finish
Configure Nautobot¶
There is a lot to configure to inform Nautobot how to integrate with SAML, so please provide the following configuration very carefully. All of these values must be correct in your nautobot_config.py
.
Important
Refer to the official Python Social Auth documentation for required SAML configuration if you run into any issues.
# Django authentication backends
AUTHENTICATION_BACKENDS = [
"social_core.backends.saml.SAMLAuth",
"nautobot.core.authentication.ObjectPermissionBackend",
]
# The https FQDN to your Nautobot instance
SOCIAL_AUTH_SAML_SP_ENTITY_ID = "https://nautobot.example.com/"
# X.509 cert/key pair used for host verification are not used for this example because
# Nautobot is directly authenticating itself to Google. Set them to empty strings.
SOCIAL_AUTH_SAML_SP_PUBLIC_CERT = ""
SOCIAL_AUTH_SAML_SP_PRIVATE_KEY = ""
# A dictionary that contains information about your app. You must specify values for
# English at a minimum.
SOCIAL_AUTH_SAML_ORG_INFO = {
"en-US": {
"name": "Nautobot",
"displayname": "Nautobot",
"url": "https://nautobot.example.com",
}
}
# Technical point of contact
SOCIAL_AUTH_SAML_TECHNICAL_CONTACT = {
"givenName": "Bob Jones",
"emailAddress": "bob@example.com"
}
# Support point of contact
SOCIAL_AUTH_SAML_SUPPORT_CONTACT = {
"givenName": "Alice Jenkins",
"emailAddress": "alice@example.com"
}
# The Entity ID URL for Google from step 3
GOOGLE_ENTITY_ID = "<Entity ID from Google>"
# The SSO URL for Google from step 3
GOOGLE_SSO_URL = "<SSO URL from Google>"
# The Certificate for Google from step 3
GOOGLE_CERTIFICATE = "<Certificate from Google>"
# The most important setting. List the Entity ID, SSO URL, and x.509 public key certificate
# for each provider that you app wants to support. We are only supporting Google for this
# example.
SOCIAL_AUTH_SAML_ENABLED_IDPS = {
"google": {
"entity_id": GOOGLE_ENTITY_ID,
"url": GOOGLE_SSO_URL,
"x509cert": GOOGLE_CERTIFICATE,
# These are used to map to User object fields in Nautobot using Google
# attribute fields we configured in step 8 of "Setup SAML in Google".
"attr_user_permanent_id": "email",
"attr_first_name": "first_name",
"attr_last_name": "last_name",
"attr_username": "email",
"attr_email": "email",
}
}
# Required for correctly redirecting when behind SSL proxy (NGINX). You may or may not need
# these depending on your production deployment. They are provided here just in case.
SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
Enable SAML in Google¶
Now that you've configured both Google and Nautobot for SAML, you still need to enable SAML for your users in your Google domain.
On Google's official site to Set up your own custom SAML application, scroll down to Turn on your SAML app and follow the remaining instructions to enable and verify SAML in Google.
Login with SAML¶
Note the provider entry we configured in SOCIAL_AUTH_SAML_ENABLED_IDPS
as google
. This will be used to login and will be referenced in the query parameter using idp=google
. For example /login/saml/?idp=google
.
This should be the URL that is mapped to the "Log in" button on the top right of the index page when you navigate to Nautobot in your browser. Clicking this link should automatically redirect you to Google, ask you to "Choose an account", log you in and redirect you back to the Nautobot home page. Your email address will also be your username.
Be sure to configure EXTERNAL_AUTH_DEFAULT_GROUPS
and EXTERNAL_AUTH_DEFAULT_PERMISSIONS
next.
SAML Metadata¶
If you need to collect SAML metadata from your Nautobot host to provide to the IDP, you can add a simple view to gather and display metadata.
from django.http import HttpResponse
from django.urls import reverse
from django.views.generic import View
from onelogin.saml2.errors import OneLogin_Saml2_Error
from social_django.utils import load_backend, load_strategy
class MetadataView(View):
"""Simple metadata view to display metadata on a nautobot page.
Import this view into your url file then add a uri path:
path("metadata/", MetadataView.as_view(), name="metadata"),
"""
def get(self, request):
complete_url = reverse("social:complete", args=("saml",))
saml_backend = load_backend(
load_strategy(request),
"saml",
redirect_uri=complete_url,
)
try:
metadata, errors = saml_backend.generate_metadata_xml()
if not errors:
return HttpResponse(content=metadata, content_type="text/xml")
except OneLogin_Saml2_Error as saml_error:
config = saml_backend.generate_saml_config()
return HttpResponse(
content=f"ERROR: {saml_error}, SAML backend config is {config}",
content_type="text/plain"
)
Azure AD¶
- In the Azure admin portal, search for and select Azure Active Directory.
- Under Manage, select App registrations -> New registration.
-
Configure the application as follows:
- Name: This is the user-facing display name for the app.
- Supported account types: This specifies the AD directories that you're allowing to authenticate with this app.
- Redirect URIs: Don't fill this out yet, it will be configured in the following steps.
-
Once the application is configured in Azure, you'll be shown the app registration's Overview page. Please take note of the Application (client) ID for use later. SSO with Azure can either be configured with OAuth2 or OpenID Connect (OIDC). When using an organization's authentication server OAuth2 is preferred; with custom Azure authentication backends, use OIDC.
- From the App registration page, click on Authentication. Under Platform configurations, select Add a platform and select Web.
-
Click on the Add a Redirect URI link on the page and configure it as follows:
- Redirect URIs: should be the Base URI plus
/complete/azuread-oauth2/
such ashttps://nautobot.example.com/complete/azuread-oauth2/
- Redirect URIs: should be the Base URI plus
-
Once the Redirect URI is set, the last thing you'll need is to generate a client secret. To do so, click on Certificates & secrets and then the New client secret option. At this point you'll need to specify the expiration for the secret. Microsoft recommends less than 12 months with a maximum of 24 months as an option. Ensure you make a note of the secret that's generated for the next step.
-
With the client secret generated, edit your
nautobot_config.py
as follows:
Azure AD - OAuth2¶
If your app is linked to the common tenant, you'll want to edit your nautobot_config.py
as follows:
AUTHENTICATION_BACKENDS = [
"social_core.backends.azuread.AzureADOAuth2",
"nautobot.core.authentication.ObjectPermissionBackend",
]
SOCIAL_AUTH_AZUREAD_OAUTH2_KEY = "<Client ID from Azure>"
SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET = "<Client Secret From Azure>"
Azure - Tenant Support¶
If your app is linked to a specific tenant instead of the common tenant, you'll want to edit your nautobot_config.py
as follows:
AUTHENTICATION_BACKENDS = [
"social_core.backends.azuread_tenant.AzureADTenantOAuth2",
"nautobot.core.authentication.ObjectPermissionBackend",
]
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY = "<Client ID from Azure>"
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET = "<Client Secret From Azure>"
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID = "<Tenant ID from Azure>"
With those settings in place your users should be able to authenticate against Azure AD and successfully login to Nautobot. However, that user will not be placed in any groups or given any permissions. In order to do so, you'll need to utilize a script to synchronize the groups passed from Azure to Nautobot after authentication succeeds. Any group permissions will need to be set manually in the Nautobot admin panel.
An example to sync groups with Azure is provided in the examples/azure_ad
folder in the root of the Nautobot repository.
Note
You may need to set UWSGI_BUFFER_SIZE
to something bigger than the default 4096 bytes in the UWSGI config if you are seeing errors like invalid request block size
in your application logs (see here for more information)