-
Hello guys, Could you please advise if it is possible to map different Azure users/groups to different privileges? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
I assume the feature isn't possible? |
Beta Was this translation helpful? Give feedback.
-
So this is actually possible with a custom pipeline, it requires netbox >= v3.2.7 (due to #9715) Once you have assigned roles to your azure netbox app you can do the following in netbox (alternatively instead of roles, other attributes included in the jwt can be used like groups) You update the pipeline like this: SOCIAL_AUTH_PIPELINE:
- 'social_core.pipeline.social_auth.social_details'
- 'social_core.pipeline.social_auth.social_uid'
- 'social_core.pipeline.social_auth.social_user'
- 'social_core.pipeline.user.get_username'
- 'social_core.pipeline.social_auth.associate_by_email'
- 'social_core.pipeline.user.create_user'
- 'social_core.pipeline.social_auth.associate_user'
- 'netbox.authentication.user_default_groups_handler'
- 'social_core.pipeline.social_auth.load_extra_data'
- 'social_core.pipeline.user.user_details'
- 'netbox.custom-pipeline.set_role' (only from django.contrib.auth.models import Group
class AuthFailed(Exception):
pass
def set_role(response, user, backend, *args, **kwargs):
'''
Get roles from JWT
Assign user to netbox group matching role
Also set is_superuser or is_staff for special roles 'superusers' and 'staff'
'''
try:
roles = response['roles']
except KeyError:
user.groups.clear()
raise AuthFailed("No role assigned")
try:
user.is_superuser = False
user.is_staff = False
for role in roles:
if role == 'superusers':
user.is_superuser = True
user.save()
continue
if role == "staff":
user.is_staff = True
user.save()
continue
group, created = Group.objects.get_or_create(name=role)
group.user_set.add(user)
except Group.DoesNotExist:
pass |
Beta Was this translation helpful? Give feedback.
-
если кому надо то вот netbox + zitadel(openidconnect) with helm chart in k8s: values.yaml replicaCount: 1
image:
repository: ghcr.io/netbox-community/netbox
tag: "v4.3.1"
pullPolicy: IfNotPresent
superuser:
existingSecret: "netbox-superuser-secret"
postgresql:
enabled: false
valkey:
enabled: false
externalDatabase:
host: "postgres.example.com"
port: 5432
database: "netbox"
username: "netbox"
existingSecretName: "postgres-secret"
existingSecretKey: "postgresql-password"
tasksDatabase:
host: "netbox-redis-master-0.netbox-redis-headless.netbox-redis.svc.cluster.local"
port: 6379
database: 0
username: ""
existingSecretName: "redis-secret"
existingSecretKey: "tasks-password"
ssl: false
insecureSkipTlsVerify: false
caCertPath: ""
sentinelService: ""
sentinelTimeout: 300
cachingDatabase:
host: "netbox-redis-master-0.netbox-redis-headless.netbox-redis.svc.cluster.local"
port: 6379
database: 1
username: ""
existingSecretName: "redis-secret"
existingSecretKey: "cache-password"
ssl: false
insecureSkipTlsVerify: false
caCertPath: ""
sentinelService: ""
sentinelTimeout: 300
persistence:
enabled: false
storages:
media:
BACKEND: "storages.backends.s3.S3Storage"
OPTIONS:
bucket_name: "netbox"
endpoint_url: "https://s3.example.com"
overrideUnitConfig:
listeners:
"0.0.0.0:8080":
pass: routes/main
"0.0.0.0:8081":
pass: routes/status
routes:
main:
- match:
uri: "/static/*"
action:
share: "/opt/netbox/netbox${uri}"
- action:
pass: applications/netbox
status:
- match:
uri: "/status/*"
action:
proxy: "http://unix:/opt/unit/unit.sock"
applications:
netbox:
type: "python 3"
path: /opt/netbox/netbox/
module: netbox.wsgi
home: /opt/netbox/venv
processes:
max: 4
spare: 1
idle_timeout: 120
access_log: /dev/stdout
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: le
hosts:
- host: "netbox.example.com"
paths:
- path: /
pathType: Prefix
backend:
service:
name: netbox
port:
number: 80
tls:
- hosts:
- netbox.example.com
secretName: netbox-crt
service:
type: ClusterIP
port: 80
resources:
requests:
cpu: "100m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"
allowedHosts:
- "netbox.example.com"
csrf:
trustedOrigins:
- "http://netbox.example.com"
- "https://netbox.example.com"
debug: false
loginRequired: true
metrics:
enabled: true
extraEnvs:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: s3-secret
key: access_key
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: s3-secret
key: secret_key
- name: SOCIAL_AUTH_OIDC_KEY
valueFrom:
secretKeyRef:
name: zitadel-secret
key: oidc_key
- name: SOCIAL_AUTH_OIDC_SECRET
valueFrom:
secretKeyRef:
name: zitadel-secret
key: oidc_secret
remoteAuth:
enabled: true
backends:
- social_core.backends.open_id_connect.OpenIdConnectAuth
extraVolumes:
- name: custom-pipeline
configMap:
name: custom-pipeline
- name: extra-py
configMap:
name: extra-py
extraVolumeMounts:
- name: custom-pipeline
mountPath: /opt/netbox/netbox/netbox/custom_pipeline.py
subPath: custom_pipeline.py
- name: extra-py
mountPath: /etc/netbox/config/extra.py
subPath: extra.py
apiVersion: v1
kind: ConfigMap
metadata:
name: custom-pipeline
namespace: netbox
data:
custom_pipeline.py: |
from django.contrib.auth.models import Group
class AuthFailed(Exception):
pass
def set_role(response, user, backend, *args, **kwargs):
'''
Get roles from JWT
Assign user to netbox group matching role
Also set is_superuser or is_staff for special roles 'superusers' and 'staff'
'''
try:
roles = response['roles']
if not isinstance(roles, list):
raise AuthFailed("Invalid roles format")
except KeyError:
user.groups.clear()
raise AuthFailed("No role assigned")
user.groups.clear()
user.is_superuser = False
user.is_staff = False
for role in roles:
if not isinstance(role, str):
raise AuthFailed(f"Invalid role type: {type(role)}")
if role == 'superusers':
user.is_superuser = True
continue
elif role == 'staff':
user.is_staff = True
continue
group, _ = Group.objects.get_or_create(name=role)
user.groups.add(group)
user.save()
---
apiVersion: v1
kind: ConfigMap
metadata:
name: extra-py
namespace: netbox
data:
extra.py: |
import os
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.social_auth.associate_by_email',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'netbox.authentication.user_default_groups_handler',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
'netbox.custom_pipeline.set_role',
)
SOCIAL_AUTH_OIDC_KEY = os.getenv('SOCIAL_AUTH_OIDC_KEY')
SOCIAL_AUTH_OIDC_SECRET = os.getenv('SOCIAL_AUTH_OIDC_SECRET')
SOCIAL_AUTH_OIDC_OIDC_ENDPOINT = 'https://zitadel.example.com'
SOCIAL_AUTH_REDIRECT_URI = 'https://netbox.example.com/oauth/complete/oidc/'
LOGOUT_REDIRECT_URL = 'https://netbox.example.com'
SOCIAL_AUTH_OIDC_SCOPE = ['roles'] |
Beta Was this translation helpful? Give feedback.
So this is actually possible with a custom pipeline, it requires netbox >= v3.2.7 (due to #9715)
Once you have assigned roles to your azure netbox app you can do the following in netbox (alternatively instead of roles, other attributes included in the jwt can be used like groups)
You update the pipeline like this: