跳转到主要内容

Django的SAML 2.0身份提供者

项目描述

djangosaml2idp

PyPi PyPI - Python Version PyPI - Django Version Apache 2.0 License

djangosaml2idp实现了Django的SAML2协议的身份提供者端。它基于PySAML2,并已准备用于生产。

欢迎任何贡献、功能请求、建议、想法等!有关更多信息,请参阅CONTRIBUTING文档

关于分支

从原始版本 https://github.com/OTA-Insight/djangosaml2idp 衍生,以提供错误修复和对 Python 和 Django 支持的升级。发布到 https://pypi.ac.cn/project/djangosaml2idp2/

安装

PySAML2 使用 XML 安全库 二进制文件来签名 SAML 断言,因此您需要通过操作系统包或通过编译源代码来安装它。最终可执行文件安装在哪里无关紧要,因为您需要在配置阶段设置其完整路径。XmlSec 至少适用于 Debian、OSX 和 Alpine Linux。

现在,您可以使用 pip 安装 djangosaml2idp 包。这将自动安装 PySAML2 及其依赖项。

pip install djangosaml2idp

配置 & 使用

您需要做的第一件事是将 djangosaml2idp 添加到已安装应用的列表中。

INSTALLED_APPS = (
    'django.contrib.admin',
    'djangosaml2idp',
    ...
)

现在,通过将其添加到 URL 配置中,将 djangosaml2idp 包包含到您的项目中。

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^idp/', include('djangosaml2idp.urls')),
    url(r'^admin/', admin.site.urls),
    ...
]

运行应用的迁移。

在您的 Django 设置中,配置您的 IdP。配置遵循 PySAML2 配置。示例项目中的 IdP 配置如下所示。

import saml2
from saml2.saml import NAMEID_FORMAT_EMAILADDRESS, NAMEID_FORMAT_UNSPECIFIED
from saml2.sigver import get_xmlsec_binary

LOGIN_URL = '/login/'
BASE_URL = 'http://localhost:9000/idp'

SAML_IDP_CONFIG = {
    'debug' : DEBUG,
    'xmlsec_binary': get_xmlsec_binary(['/opt/local/bin', '/usr/bin']),
    'entityid': '%s/metadata' % BASE_URL,
    'description': 'Example IdP setup',

    'service': {
        'idp': {
            'name': 'Django localhost IdP',
            'endpoints': {
                'single_sign_on_service': [
                    ('http://localhost:9000/idp/sso/post/', saml2.BINDING_HTTP_POST),
                    ('http://localhost:9000/idp/sso/redirect/', saml2.BINDING_HTTP_REDIRECT),
                ],
                "single_logout_service": [
                    ("http://localhost:9000/idp/slo/post/", saml2.BINDING_HTTP_POST),
                    ("http://localhost:9000/idp/slo/redirect/", saml2.BINDING_HTTP_REDIRECT)
                ],
            },
            'name_id_format': [NAMEID_FORMAT_EMAILADDRESS, NAMEID_FORMAT_UNSPECIFIED],
            'sign_response': True,
            'sign_assertion': True,
            'want_authn_requests_signed': True,
        },
    },

    # Signing
    'key_file': BASE_DIR + '/certificates/private.key',
    'cert_file': BASE_DIR + '/certificates/public.cert',
    # Encryption
    'encryption_keypairs': [{
        'key_file': BASE_DIR + '/certificates/private.key',
        'cert_file': BASE_DIR + '/certificates/public.cert',
    }],
    'valid_for': 365 * 24,
}

请注意,配置需要私钥和公共证书在文件系统中可用,以便对消息进行签名和加密。

接下来需要添加服务提供商及其配置,这可以通过 Django 管理界面完成。为与 IdP 通信的每个 SP 添加一个条目。添加本地元数据 xml 的副本或设置远程元数据 url。为用户属性到 SAML 字段的属性映射添加映射,或保留默认映射,它将被自动填充。

每个 SP 可以覆盖多个属性。如果它们没有被显式覆盖,它们将使用为您的 Django 安装配置的“全局”设置。如果没有设置这些设置,将使用一些默认值,如配置 SP 时管理员所示。SP 的最终配置,包括其自己的设置、实例设置和默认值,将在管理员中以摘要形式显示。

其他可选配置选项

SAML_IDP_SPCONFIG 设置中,您可以定义一个 processor,其值是一个字符串,包含到类的点路径。这是一个自定义某些访问控制检查的钩子。默认情况下,使用的是包含的 BaseProcessor,它允许每个用户在 IdP 上登录。您可以通过继承 BaseProcessor 并覆盖其 has_access(self, request) 方法来自定义此行为。此方法应根据用户是否有权限登录 SP / IdP 返回 true 或 false。处理器具有 SP 实体 ID,作为 self._entity_id 可用,并作为 has_access 函数的参数接收请求(其中包含已认证的 request.user)。这样,您应该有足够的灵活性来执行所需的任何检查。可以在包含的示例 IdP 中找到示例 processor 子类。使用此元数据 xml 来配置您的 SP。将 SP 的元数据 xml 放在配置字典中指定的位置(如上面的示例中的 sp_metadata.xml)。

如果没有自定义设置,用户将通过您使用的用户模型的 USERNAME_FIELD 属性进行识别。根据 Django 默认设置,这将是被户名。您可以通过将 SAML_IDP_DJANGO_USERNAME_FIELD 添加到设置中,并将其值设置为在您的用户实例上使用的属性来自定义用于标识的字段。

您还可以设置其他默认设置,以在 SP 没有覆盖的情况下使用,例如 SAML_AUTHN_SIGN_ALGSAML_AUTHN_DIGEST_ALGSAML_ENCRYPT_AUTHN_RESPONSE。如果需要在 django 设置中设置它们,它们将在没有覆盖的情况下用于此实例上的所有 ServiceProviders 配置。例如:

SAML_AUTHN_SIGN_ALG = saml2.xmldsig.SIG_RSA_SHA256
SAML_AUTHN_DIGEST_ALG = saml2.xmldsig.DIGEST_SHA256

如果您的SP未在元数据中正确公开validuntil,您可以使用以下方式为其提供回退设置:

SAML_IDP_FALLBACK_EXPIRATION_DAYS = 30

在ServiceProvider中,processorattribute_mapping字段的默认值可以通过设置来设置(此处显示的值是默认值)

SAML_IDP_SP_FIELD_DEFAULT_PROCESSOR = 'djangosaml2idp.processors.BaseProcessor'
SAML_IDP_SP_FIELD_DEFAULT_ATTRIBUTE_MAPPING = {"email": "email", "first_name": "first_name", "last_name": "last_name", "is_staff": "is_staff", "is_superuser": "is_superuser"}

自定义错误处理

djangosaml2idp在遇到错误时会渲染一个非常基本的错误页面,指示发生了错误,错误类型,以及可能的一个额外消息。HTTP状态码取决于发生的错误。它还会以错误严重性记录异常。您可以通过使用SAML_IDP_ERROR_VIEW_CLASS设置来自定义此设置。将此设置为到您自定义(基于类的)视图的点的导入路径以使用它。您可能希望使用自己的模板和样式来显示错误消息。如果您从提供的djangosaml2idp.error_views.SamlIDPErrorView派生类,则在模板中有以下变量可供使用:

exception

发生的异常实例

exception_type

发生的异常的类

exception_msg

异常的消息(通过执行str(exception)

extra_message

如果没有给出特定异常,则表示发生了错误,或者在exception_msg旁边的一个额外消息

最简单的覆盖方法是派生自SamlIDPErrorView并仅使用自己的错误模板。您可以使用任何基于类的视图;不必要派生内置错误视图。示例项目包含一个使用自定义模板和样式的自定义视图的示例;取消注释SAML_IDP_ERROR_VIEW_CLASS设置,它将使用自定义视图和自定义模板。

多因素认证支持

添加多因素支持有三个主要组件。

  1. 如上所述,将djangosaml2idp.processors.BaseProcessor派生为子类。您需要覆盖enable_multifactor()方法以检查是否应启用多因素认证。如果应为所有用户始终启用多因素认证,则直接将此设置为True)。默认情况下,它无条件返回False,不强制执行多因素认证。

  2. djangosaml2idp.views.ProcessMultiFactorView视图派生为针对您的环境进行适当的调用。在multifactor_is_valid方法中实现您的自定义验证逻辑:这可能调用辅助脚本、内部短信触发服务、仅IdP可以访问的数据源或外部第二因素提供程序(例如Symantec VIP)。默认情况下,此视图将记录调用并重定向。

3. 在settings.py中添加一个条目,其中包含表示您的多因素视图路径的字符串。第一个包应该是应用程序名称:SAML_IDP_MULTIFACTOR_VIEW = “this.is.the.path.to.your.multifactor.view

运行测试套件

requirements-dev.txt中安装开发依赖项

pip install -r requirements-dev.txt

从项目根目录运行测试套件

tox -e format  # to run linting
tox -e py3.7-django3.0  # to run the tests
tox -e typing  # to run typechecking, this is allowed to fail

在打开合并请求时也会使用CI运行测试。

示例项目

example_project目录包含一个裸机演示设置,用于演示登录/注销功能。它由使用djangosaml2实现的Service Provider和一个使用djangosaml2idp的Identity Provider组成。该文件夹中的readme包含有关如何运行它的更多信息。

项目详情


下载文件

下载适合您平台的应用程序。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

djangosaml2idp2-0.8.0.tar.gz (31.9 kB 查看哈希值)

上传时间 源码

构建分发版

djangosaml2idp2-0.8.0-py2.py3-none-any.whl (30.5 kB 查看哈希值)

上传时间 Python 2 Python 3

由以下支持