Skip to content

Instantly share code, notes, and snippets.

@nahun
Last active November 5, 2024 09:42
Show Gist options
  • Save nahun/5d4d715ca37a2465aaf59ab152413dc2 to your computer and use it in GitHub Desktop.
Save nahun/5d4d715ca37a2465aaf59ab152413dc2 to your computer and use it in GitHub Desktop.
NetBox with AzureAD OAuth

NetBox with AzureAD SSO using OAuth

This is an example setup with NetBox using AzureAD for authentication. It uses the Python Social Auth library.

Most of this was taken from this gist: https://gist.github.com/leoluk/16d91ec22d833945c7ac7ed2b3b05a27

This is written to support NetBox v2.10 to v3.0. I'll try to note differences for 2.9 or earlier.

NOTE: NetBox v3.1 added basic support for using social_auth so most of this is no longer required and can be placed in the configuration.py file.

AzureAD Setup

You will need an AzureAD App Registration (Service Principal) created for NetBox and create a client secret to use. You'll need the Client ID and Tenant ID as well.

Within the App Registration create app roles that will be used to assign users to specific groups. The app role value must be the same as the NetBox group name. See the Microsoft docs on app roles. This step can be skipped if you remove the references to the set_role method in custom_pipeline.py.

The set_username method in custom_pipeline.py will set the user's UPN attribute as the NetBox username. Set this to any attribute you want.

Requirements

Place the local_requirements.txt file in the NetBox root directory (/opt/netbox by default). See the NetBox docs. Install the Python package in the requirements file.

Rename default settings.py to upstream_settings.py

To overwrite the default settings.py and keep upgrades easier, move/rename the default settings.py to upstream_settings.py.

Modify the settings.py file

Enter your AzureAD information to the settings.py file.

Merge your configuration.py

The configuration.py provided here is just what is needed to setup this authentication. Merge it with your own configuration.py.

Copy Files

Copy each file to the $INSTALL_ROOT/netbox/netbox/ directory

  • custom_middleware.py
  • custom_urls.py
  • custom_pipeline.py
  • settings.py

Restart NetBox

systemctl restart netbox netbox-rq

LOGIN_REQUIRED = True
REMOTE_AUTH_BACKEND = 'social_core.backends.azuread_tenant.AzureADTenantOAuth2'
"""
Custom LOGIN_REQUIRED middleware which allows OAuth URLs.
"""
from netbox.middleware import LoginRequiredMiddleware # v2.10+
# v2.9 or earlier
#from utilities.middleware import LoginRequiredMiddleware
from django.conf import settings
class CustomLoginRequiredMiddleware(LoginRequiredMiddleware):
def __call__(self, request):
if settings.LOGIN_REQUIRED and not request.user.is_authenticated:
if request.path_info.startswith('/oauth/'):
return self.get_response(request)
return super(CustomLoginRequiredMiddleware, self).__call__(request)
from django.contrib.auth.models import Group
class AuthFailed(Exception):
pass
def set_role(response, user, backend, *args, **kwargs):
try:
role = response['roles'][0]
except KeyError:
raise AuthFailed("No role assigned")
try:
group = Group.objects.get(name="{}".format(role))
except Group.DoesNotExist:
raise AuthFailed("Unknown role")
group.user_set.add(user)
def set_username(response, *args, **kwargs):
return { 'username': response['upn'].lower() }
"""
Override upstream urls.py for OAuth login
"""
from netbox.urls import *
urlpatterns = urlpatterns + [
path(r'oauth/', include('social_django.urls', namespace='social')),
]
social-auth-app-django
"""
Override the Netbox settings.py for customizations outside of configuration.py.
"""
import os
from netbox.upstream_settings import *
# OAuth monkey patching
MIDDLEWARE = [
'netbox.custom_middleware.CustomLoginRequiredMiddleware' if
x == 'netbox.middleware.LoginRequiredMiddleware' else x # v2.10+
# v2.9 or earlier
#x == 'utilities.middleware.LoginRequiredMiddleware' else x
for x in MIDDLEWARE
]
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_RESOURCE = '{{ AzureAD App Registration Client ID }}'
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY = '{{ AzureAD App Registration Client ID }}'
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET = '{{ AzureAD App Registration Client Secret }}'
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID = '{{ Azure Tenant ID }}'
LOGIN_URL = '/oauth/login/azuread-tenant-oauth2/'
ROOT_URLCONF = 'netbox.custom_urls'
SOCIAL_AUTH_POSTGRES_JSONFIELD = True
INSTALLED_APPS.append('social_django')
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'netbox.custom_pipeline.set_username',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
'netbox.custom_pipeline.set_role'
)
@nahun
Copy link
Author

nahun commented Sep 12, 2023

@rcalma This doc is out-of-date as mentioned before and at the top.

NOTE: NetBox v3.1 added basic support for using social_auth so most of this is no longer required and can be placed in the configuration.py file.

See this comment too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment