使用ZITADEL为Python Django应用添加身份认证功能
前言
在现代Web应用开发中,身份认证和授权是必不可少的功能。ZITADEL作为一个开源的身份与访问管理(IAM)平台,为开发者提供了强大的认证和授权能力。本文将详细介绍如何在Python Django应用中集成ZITADEL,实现基于角色的用户认证系统。
准备工作
ZITADEL配置
在开始编码前,我们需要在ZITADEL控制台完成一些基础配置:
-
项目角色设置:
- 创建三个角色:
admin
(超级用户)、staff
(员工)和user
(普通用户) - 确保"Assert Roles On Authentication"选项已启用
- 为用户分配相应的角色
- 创建三个角色:
-
应用配置:
- 创建一个Web应用类型的新应用
- 选择授权码(Authorization Code)授权类型
- 配置重定向URI和登出后URI
- 记录生成的客户端ID和密钥
开发环境搭建
Python环境配置
建议使用Python 3.8+版本,并创建虚拟环境隔离项目依赖:
python -m venv venv
source venv/bin/activate # Linux/macOS
venv\Scripts\activate # Windows
安装依赖
创建requirements.txt
文件并添加以下依赖:
django>=4.0
python-dotenv>=0.19
mozilla-django-oidc>=2.0
然后安装依赖:
pip install -r requirements.txt
Django项目配置
基础设置
在settings.py
中添加必要的配置:
INSTALLED_APPS = [
# ...
'mozilla_django_oidc', # 在auth之后加载
]
MIDDLEWARE = [
# ...
'mozilla_django_oidc.middleware.SessionRefresh',
]
AUTHENTICATION_BACKENDS = (
'mysite.backend.PermissionBackend',
)
OIDC配置
添加ZITADEL相关的OIDC配置:
# OIDC配置
OIDC_RP_CLIENT_ID = os.getenv('OIDC_RP_CLIENT_ID')
OIDC_RP_CLIENT_SECRET = os.getenv('OIDC_RP_CLIENT_SECRET')
OIDC_OP_BASE_URL = os.getenv('OIDC_OP_BASE_URL')
OIDC_OP_AUTHORIZATION_ENDPOINT = f"{OIDC_OP_BASE_URL}/oauth/v2/authorize"
OIDC_OP_TOKEN_ENDPOINT = f"{OIDC_OP_BASE_URL}/oauth/v2/token"
OIDC_OP_USER_ENDPOINT = f"{OIDC_OP_BASE_URL}/oidc/v1/userinfo"
OIDC_OP_JWKS_ENDPOINT = f"{OIDC_OP_BASE_URL}/oauth/v2/keys"
OIDC_OP_LOGOUT_ENDPOINT = f"{OIDC_OP_BASE_URL}/oidc/v1/end_session"
OIDC_OP_LOGOUT_URL_METHOD = 'mysite.backend.provider_logout'
OIDC_RP_SIGN_ALGO = 'RS256'
OIDC_STORE_ACCESS_TOKEN = True
OIDC_STORE_ID_TOKEN = True
OIDC_RP_SCOPES = 'openid profile email urn:zitadel:iam:org:project:id:{ZITADEL_PROJECT}:aud'
环境变量配置
创建.env
文件存储敏感信息:
ZITADEL_PROJECT=你的项目ID
OIDC_RP_CLIENT_ID=你的客户端ID
OIDC_RP_CLIENT_SECRET=你的客户端密钥
OIDC_OP_BASE_URL=你的ZITADEL实例基础URL
自定义认证后端
我们需要创建一个自定义认证后端来处理ZITADEL返回的角色信息:
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
class PermissionBackend(OIDCAuthenticationBackend):
def verify_claims(self, claims):
# 验证用户是否具有所需角色
return 'urn:zitadel:iam:org:project:roles' in claims
def create_user(self, claims):
user = super().create_user(claims)
return self.update_user(user, claims)
def update_user(self, user, claims):
roles = claims.get('urn:zitadel:iam:org:project:roles', [])
# 根据角色设置用户权限
user.is_superuser = 'admin' in roles
user.is_staff = user.is_superuser or 'staff' in roles
user.save()
return user
URL路由配置
在urls.py
中添加OIDC相关的路由:
from django.urls import path, include
urlpatterns = [
# ...
path('oidc/', include('mozilla_django_oidc.urls')),
]
视图保护
在视图上添加装饰器来控制访问权限:
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.contrib.admin.views.decorators import staff_member_required
# 需要登录的视图
@method_decorator(login_required, name='dispatch')
class ProtectedView(View):
pass
# 需要员工权限的视图
@method_decorator(staff_member_required, name='dispatch')
class StaffView(View):
pass
数据库迁移与运行
执行数据库迁移:
python manage.py migrate
启动开发服务器:
python manage.py runserver
测试与验证
访问以下URL测试功能:
/polls
- 需要登录/admin
- 需要管理员权限
安全注意事项
- 永远不要将
.env
文件或敏感信息提交到版本控制 - 在生产环境中使用HTTPS
- 定期轮换客户端密钥
- 实施适当的会话管理策略
总结
通过本文,我们成功地在Django应用中集成了ZITADEL身份认证系统,实现了基于角色的访问控制。这种集成方式不仅安全可靠,而且易于维护和扩展。开发者可以根据实际需求进一步定制认证流程和权限控制逻辑。
进阶建议
- 探索ZITADEL的API实现更复杂的授权逻辑
- 考虑实现多因素认证增强安全性
- 研究ZITADEL的组织和项目管理功能
- 监控和分析用户登录行为
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考