Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/administration/authentication/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,22 @@ REMOTE_AUTH_BACKEND = 'social_core.backends.google.GoogleOAuth2'
NetBox supports single sign-on authentication via the [python-social-auth](https://github.com/python-social-auth) library. To enable SSO, specify the path to the desired authentication backend within the `social_core` Python package. Please see the complete list of [supported authentication backends](https://github.com/python-social-auth/social-core/tree/master/social_core/backends) for the available options.

Most remote authentication backends require some additional configuration through settings prefixed with `SOCIAL_AUTH_`. These will be automatically imported from NetBox's `configuration.py` file. Additionally, the [authentication pipeline](https://python-social-auth.readthedocs.io/en/latest/pipeline.html) can be customized via the `SOCIAL_AUTH_PIPELINE` parameter. (NetBox's default pipeline is defined in `netbox/settings.py` for your reference.)

#### Configuring the SSO module's appearance

The way a remote authentication backend is displayed to the user on the login
page may be adjusted via the `SOCIAL_AUTH_BACKEND_ATTRS` parameter, defaulting
to an empty dictionary. This dictionary maps a `social_core` module's name (ie.
`REMOTE_AUTH_BACKEND.name`) to a couple of parameters, `(display_name, icon)`.

The `display_name` is the name displayed to the user on the login page. The
icon may either be the URL of an icon; refer to a [Material Design
Icons](https://github.com/google/material-design-icons) icon's name; or be
`None` for no icon.

For instance, the OIDC backend may be customized with
```python
SOCIAL_AUTH_BACKEND_ATTRS = {
'oidc': ("My awesome SSO", "login"),
}
```
12 changes: 11 additions & 1 deletion netbox/account/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,20 @@ def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)

def gen_auth_data(self, name, url, params):
display_name, icon_name = get_auth_backend_display(name)
display_name, icon_source = get_auth_backend_display(name)

icon_name = None
icon_img = None
if icon_source:
if '://' in icon_source:
icon_img = icon_source
else:
icon_name = icon_source

return {
'display_name': display_name,
'icon_name': icon_name,
'icon_img': icon_img,
'url': f'{url}?{urlencode(params)}',
}

Expand Down
7 changes: 5 additions & 2 deletions netbox/netbox/authentication/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,15 @@
'okta-openidconnect': ('Okta (OIDC)', None),
'salesforce-oauth2': ('Salesforce', 'salesforce'),
}
# Override with potential user configuration
AUTH_BACKEND_ATTRS.update(getattr(settings, 'SOCIAL_AUTH_BACKEND_ATTRS', {}))


def get_auth_backend_display(name):
"""
Return the user-friendly name and icon name for a remote authentication backend, if known. Defaults to the
raw backend name and no icon.
Return the user-friendly name and icon name for a remote authentication backend, if
known. Obtained from the defaults dictionary AUTH_BACKEND_ATTRS, overridden by the
setting `SOCIAL_AUTH_BACKEND_ATTRS`. Defaults to the raw backend name and no icon.
"""
return AUTH_BACKEND_ATTRS.get(name, (name, None))

Expand Down
3 changes: 2 additions & 1 deletion netbox/templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ <h2 class="text-center mb-4">{% trans "Log In" %}</h2>
{% for backend in auth_backends %}
<div class="col">
<a href="{{ backend.url }}" class="btn w-100">
{% if backend.icon_name %}<i class="mdi mdi-{{ backend.icon_name }}"></i>{% endif %}
{% if backend.icon_name %}<i class="mdi mdi-{{ backend.icon_name }}"></i>
{% elif backend.icon_img %}<img src="{{ backend.icon_img }}" height="24" class="me-2" />{% endif %}
{{ backend.display_name }}
</a>
</div>
Expand Down