当前位置: 首页 > 知识库问答 >
问题:

NoneType对象在Django中没有属性require_signatureSAML 2身份验证

百里承业
2023-03-14

我使用简单的SAML PHP作为我的IDP(身份提供者),使用Django SAML 2 Auth将SAML 2身份验证集成到我的Django应用程序(即SP(服务提供者))。

这两个工具的配置如下:

简单SAML PHP:

docker run --name=saml_idp -p 8080:8080 -p 8443:8443 -e SIMPLESAMLPHP_SP_ENTITY_ID=http://0.0.0.0:8000/saml2_auth/metadata.xml -e SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE=http://0.0.0.0:8000/saml2_auth/acs/ --network host -d kristophjunge/test-saml-idp

简单SAML PHP元数据:

<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="http://127.0.0.1:8080/simplesaml/saml2/idp/metadata.php">
  <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <md:KeyDescriptor use="signing">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
          <ds:X509Certificate>MIIDXTCCAkWgAwIBAgIJALmVVuDWu4NYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYxMjMxMTQzNDQ3WhcNNDgwNjI1MTQzNDQ3WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzUCFozgNb1h1M0jzNRSCjhOBnR+uVbVpaWfXYIR+AhWDdEe5ryY+CgavOg8bfLybyzFdehlYdDRgkedEB/GjG8aJw06l0qF4jDOAw0kEygWCu2mcH7XOxRt+YAH3TVHa/Hu1W3WjzkobqqqLQ8gkKWWM27fOgAZ6GieaJBN6VBSMMcPey3HWLBmc+TYJmv1dbaO2jHhKh8pfKw0W12VM8P1PIO8gv4Phu/uuJYieBWKixBEyy0lHjyixYFCR12xdh4CA47q958ZRGnnDUGFVE1QhgRacJCOZ9bd5t9mr8KLaVBYTCJo5ERE8jymab5dPqe5qKfJsCZiqWglbjUo9twIDAQABo1AwTjAdBgNVHQ4EFgQUxpuwcs/CYQOyui+r1G+3KxBNhxkwHwYDVR0jBBgwFoAUxpuwcs/CYQOyui+r1G+3KxBNhxkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAAiWUKs/2x/viNCKi3Y6blEuCtAGhzOOZ9EjrvJ8+COH3Rag3tVBWrcBZ3/uhhPq5gy9lqw4OkvEws99/5jFsX1FJ6MKBgqfuy7yh5s1YfM0ANHYczMmYpZeAcQf2CGAaVfwTTfSlzNLsF2lW/ly7yapFzlYSJLGoVE+OHEu8g5SlNACUEfkXw+5Eghh+KzlIN7R6Q7r2ixWNFBC/jWf7NKUfJyX8qIG5md1YUeT6GBW9Bm2/1/RiO24JTaYlfLdKK9TYb8sG5B+OLab2DImG99CJ25RkAcSobWNF5zD0O6lgOo3cEdB/ksCq3hmtlC/DlLZ/D8CJ+7VuZnS1rR2naQ==</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:KeyDescriptor use="encryption">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
          <ds:X509Certificate>MIIDXTCCAkWgAwIBAgIJALmVVuDWu4NYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYxMjMxMTQzNDQ3WhcNNDgwNjI1MTQzNDQ3WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzUCFozgNb1h1M0jzNRSCjhOBnR+uVbVpaWfXYIR+AhWDdEe5ryY+CgavOg8bfLybyzFdehlYdDRgkedEB/GjG8aJw06l0qF4jDOAw0kEygWCu2mcH7XOxRt+YAH3TVHa/Hu1W3WjzkobqqqLQ8gkKWWM27fOgAZ6GieaJBN6VBSMMcPey3HWLBmc+TYJmv1dbaO2jHhKh8pfKw0W12VM8P1PIO8gv4Phu/uuJYieBWKixBEyy0lHjyixYFCR12xdh4CA47q958ZRGnnDUGFVE1QhgRacJCOZ9bd5t9mr8KLaVBYTCJo5ERE8jymab5dPqe5qKfJsCZiqWglbjUo9twIDAQABo1AwTjAdBgNVHQ4EFgQUxpuwcs/CYQOyui+r1G+3KxBNhxkwHwYDVR0jBBgwFoAUxpuwcs/CYQOyui+r1G+3KxBNhxkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAAiWUKs/2x/viNCKi3Y6blEuCtAGhzOOZ9EjrvJ8+COH3Rag3tVBWrcBZ3/uhhPq5gy9lqw4OkvEws99/5jFsX1FJ6MKBgqfuy7yh5s1YfM0ANHYczMmYpZeAcQf2CGAaVfwTTfSlzNLsF2lW/ly7yapFzlYSJLGoVE+OHEu8g5SlNACUEfkXw+5Eghh+KzlIN7R6Q7r2ixWNFBC/jWf7NKUfJyX8qIG5md1YUeT6GBW9Bm2/1/RiO24JTaYlfLdKK9TYb8sG5B+OLab2DImG99CJ25RkAcSobWNF5zD0O6lgOo3cEdB/ksCq3hmtlC/DlLZ/D8CJ+7VuZnS1rR2naQ==</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://127.0.0.1:8080/simplesaml/saml2/idp/SingleLogoutService.php"/>
    <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
    <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://127.0.0.1:8080/simplesaml/saml2/idp/SSOService.php"/>
  </md:IDPSSODescriptor>
</md:EntityDescriptor>

Django SAML 2 Auth:

XMLSEC_BINARY = '/usr/local/bin/xmlsec1'

# The configurations set here need to be the same as the IDP / SP configuration, that is
# described in the metadata files (https://www.samltool.com/online_tools.php)
SAML2_AUTH = {
    # Metadata is required, choose either remote URL or local file path
    'METADATA_AUTO_CONF_URL': 'http://127.0.0.1:8080/simplesaml/saml2/idp/metadata.php',
    'METADATA_LOCAL_FILE_PATH': '/code/app/metadata_idp.xml',

    # Optional settings below
    'DEFAULT_NEXT_URL': '/',
    'CREATE_USER': 'FALSE',
    'NEW_USER_PROFILE': {
        'USER_GROUPS': [],
        'ACTIVE_STATUS': True,
        'STAFF_STATUS': True,
        'SUPERUSER_STATUS': False
    },
    # Change user name / password to corresponding SAML2 user profile attributes
    'ATTRIBUTES_MAP': {
        'username': 'username',
        'password': 'password'
    },
    # 'TRIGGER': {
    #     'CREATE_USER': 'path.to.your.new.user.hook.method',
    #     'BEFORE_LOGIN': 'path.to.your.login.hook.method',
    # },
    # Custom URL to validate incoming SAML requests against
    'ASSERTION_URL': 'http://0.0.0.0:8000/saml2_auth/acs/',
    # Populates the Issuer element in authn request
    'ENTITY_ID': 'http://0.0.0.0:8000/saml2_auth/metadata.xml'
}

Django SAML 2 Auth metadata:

<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" validUntil="2019-12-09T14:01:55Z" cacheDuration="PT604800S" entityID="http://0.0.0.0:8000/saml2_auth/metadata.xml">
  <md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <md:KeyDescriptor use="signing">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
          <ds:X509Certificate>MIIFazCCA1OgAwIBAgIUaIcEZyo+RfcwO/s/iug723Rs0BMwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTEyMDYxNzEzNDZaFw0yMDEyMDUxNzEzNDZaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9COPzO/nV2t2c3nh0a5UvVD9S8wK1SDaiPWeJ2d8MjOV4NPQlTtKLG1JZcoOlNViZY+ywsIZFTYCyHIuoSX3gyd2p4PGGevip/SwWPxOQ00PStOuCMBJv9reoZEsIJd9V40FTbPCeNktWyO0u2NUWJmJnMOvhzaXvV4yNHZC3aUcYvuBmtodpBSuzLYgnsKJyCUV7XEwKrrYeHzZXsTTRmmnXxTFqs+zAFuhQRoRfMXaQjDFFwToX/fZ9YFlM3LdtkBv3gImSo5nuR1oP9k42H3B0ejK+i/CEzRk5y+4B5yIZLnnP+DVBqf9BXWeelYkaenU39gxH9Sb8dnBMR31FnXibUjrRXYB0t7a4Fl+ZLT3U7l1BHjqXJ2WO5/hybQ/dxUOJCoT93z9MLFegQfIx7AfJkQ/6xwKTgt7iCFFOswzPcvw/hzx//Cu2JxEaunYdHiJiQgDdZtIPn22BjJ2v2gxjKGUIascDmC78VH5ZA40XCXewHma6CLOWQ8FggKzYWr0WwCu+J/EmqDDPuZE/Qlz6ij2akfUh2LRpFZF5coKy9vpxiyeak9+3lKrTWkdflyd2uBhsqPoeXNvwrf4yC4TPNuIDGNYgstq80uCmaK4qBh+TGvnpeD8/3F+7q/t10hNJDftuKgz4zmIugcBs6x7CTMZjhJ+7bBAbzI4IJwIDAQABo1MwUTAdBgNVHQ4EFgQUVXGXpXGp2c8JC9+y/8a1t68Op54wHwYDVR0jBBgwFoAUVXGXpXGp2c8JC9+y/8a1t68Op54wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAudPK04qXdjVNSBS6kA2eitkePDfbn61uIe8zXUYMsXYXD97qrwuzKU4vPpvP9zjjRm24hYAuOQ6VARNBHfD2VDXcg/J2r8EuVS+/acElb3TIDJmFNYxVwahhC3ZQ27q8BOVWEUR22biloAkTAqbpZeugHVOCMRxS9DvBTOjw9RFV15qc7nzs9P9yM3Kss+TM6hAFetCi0LIhOTujv3j6GPzMQ9jITb4T+EdjvmazzjSEYPmm5QwVaL98hTlHfTSB8Gsx6Vh/K859ZDrNyzbqck4DKd1WcGjykmcEQQx6ixGGDx/nRKQyW5aYKD2a+AL5WcFqwIc974kH3fNKYyeIgucVmjeJsivzMx8u29AQ5RPLRW8iCGuX2+igNGG7NaHN2psaSnYW9Z8NCO7R9AQHuc9s5TJfV60gJ5JqxARL45veeE6ALiXGKEHMHSXBpHWKSF04eTNgGhq8IkJeQPR8Gv7aGu6lMn040C/YtwgYVuqsgtYRylhdPBUEHGhjdFBUlmcSnaDv8ro7J8IkafMACHgp8U27C7bHg6bwAbpiKYojKvCpZDBpGsAQui4JaCR1Z6CGdkTAXzArRIxgNG17m4vhJQOMyQCeIbryy510mjEWwircPQ2lFpO1KEIL7QXUVUxbpRCGfsEg4Oeqvhl57az2/UG/dSadIJLuVOxHDdc=</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:KeyDescriptor use="encryption">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
          <ds:X509Certificate>MIIFazCCA1OgAwIBAgIUaIcEZyo+RfcwO/s/iug723Rs0BMwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTEyMDYxNzEzNDZaFw0yMDEyMDUxNzEzNDZaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9COPzO/nV2t2c3nh0a5UvVD9S8wK1SDaiPWeJ2d8MjOV4NPQlTtKLG1JZcoOlNViZY+ywsIZFTYCyHIuoSX3gyd2p4PGGevip/SwWPxOQ00PStOuCMBJv9reoZEsIJd9V40FTbPCeNktWyO0u2NUWJmJnMOvhzaXvV4yNHZC3aUcYvuBmtodpBSuzLYgnsKJyCUV7XEwKrrYeHzZXsTTRmmnXxTFqs+zAFuhQRoRfMXaQjDFFwToX/fZ9YFlM3LdtkBv3gImSo5nuR1oP9k42H3B0ejK+i/CEzRk5y+4B5yIZLnnP+DVBqf9BXWeelYkaenU39gxH9Sb8dnBMR31FnXibUjrRXYB0t7a4Fl+ZLT3U7l1BHjqXJ2WO5/hybQ/dxUOJCoT93z9MLFegQfIx7AfJkQ/6xwKTgt7iCFFOswzPcvw/hzx//Cu2JxEaunYdHiJiQgDdZtIPn22BjJ2v2gxjKGUIascDmC78VH5ZA40XCXewHma6CLOWQ8FggKzYWr0WwCu+J/EmqDDPuZE/Qlz6ij2akfUh2LRpFZF5coKy9vpxiyeak9+3lKrTWkdflyd2uBhsqPoeXNvwrf4yC4TPNuIDGNYgstq80uCmaK4qBh+TGvnpeD8/3F+7q/t10hNJDftuKgz4zmIugcBs6x7CTMZjhJ+7bBAbzI4IJwIDAQABo1MwUTAdBgNVHQ4EFgQUVXGXpXGp2c8JC9+y/8a1t68Op54wHwYDVR0jBBgwFoAUVXGXpXGp2c8JC9+y/8a1t68Op54wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAudPK04qXdjVNSBS6kA2eitkePDfbn61uIe8zXUYMsXYXD97qrwuzKU4vPpvP9zjjRm24hYAuOQ6VARNBHfD2VDXcg/J2r8EuVS+/acElb3TIDJmFNYxVwahhC3ZQ27q8BOVWEUR22biloAkTAqbpZeugHVOCMRxS9DvBTOjw9RFV15qc7nzs9P9yM3Kss+TM6hAFetCi0LIhOTujv3j6GPzMQ9jITb4T+EdjvmazzjSEYPmm5QwVaL98hTlHfTSB8Gsx6Vh/K859ZDrNyzbqck4DKd1WcGjykmcEQQx6ixGGDx/nRKQyW5aYKD2a+AL5WcFqwIc974kH3fNKYyeIgucVmjeJsivzMx8u29AQ5RPLRW8iCGuX2+igNGG7NaHN2psaSnYW9Z8NCO7R9AQHuc9s5TJfV60gJ5JqxARL45veeE6ALiXGKEHMHSXBpHWKSF04eTNgGhq8IkJeQPR8Gv7aGu6lMn040C/YtwgYVuqsgtYRylhdPBUEHGhjdFBUlmcSnaDv8ro7J8IkafMACHgp8U27C7bHg6bwAbpiKYojKvCpZDBpGsAQui4JaCR1Z6CGdkTAXzArRIxgNG17m4vhJQOMyQCeIbryy510mjEWwircPQ2lFpO1KEIL7QXUVUxbpRCGfsEg4Oeqvhl57az2/UG/dSadIJLuVOxHDdc=</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://0.0.0.0:8000/saml2_auth/acs/" index="1"/>
  </md:SPSSODescriptor>
</md:EntityDescriptor>

当我访问0.0.0.0:8000/saml2_auth/login时,我被重定向到127 . 0 . 0 . 1:8080/simple SAML/SAML 2/IDP/SSO service . PHP,在那里我登录并返回到0.0.0.0:8000/saml2_auth/acs/

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django_saml2_auth/views.py", line 159, in acs
    resp, entity.BINDING_HTTP_POST)
  File "/usr/local/lib/python3.7/site-packages/saml2/client_base.py", line 714, in parse_authn_request_response
    binding, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/saml2/entity.py", line 1205, in _parse_response
    response.require_signature = require_signature
AttributeError: 'NoneType' object has no attribute 'require_signature'

我读过“NoneType”对象没有“require_signature”属性,但这没有多大帮助。如何解决此问题。

Obs ¹:认证是使用 openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -days 365 生成的

Obs²:我还创建了一个Javascript示例,一切都很好

Obs ³:当我返回到 /asc 时,会话已在 IDP 中设置,并且也返回到 SP:

共有1个答案

卫弘义
2023-03-14

当我将一些为Flask编写的示例代码移植到Django/DRF时,我没有正确地获取信息,这意味着SAMLACK只是一个乱码字符串,因此require_signature没有价值。

Base64 解码 SAMLResponse 内容就成功了。如果这是在他们的文档的某个地方,我肯定找不到它。也许它应该是“显而易见的”,因为它是标记语言,需要编码?

 类似资料:
  • 我正在与Django CBV合作,我第一次尝试使用表单集。我想同时填写两个表单,并将外键作为两者之间的公共元素。 我有两种型号: 我在我的表单python文件中定义了表单集: 最重要的是,我的视图是在cruds.py文件中定义的,如下所示: 该模板显示良好,具有通用的表单集,但当我想提交这个组合的表单时,我得到了这个问题: 异常值:“NoneType”对象没有属性“id” 这是回溯: 追踪: 文件

  • 如果pk_col值为空,则应打印未定义的主键。但我得到了这个错误。“NoneType”对象没有属性“rdd”。

  • 问题内容: 下面的代码给出了错误: 码: 问题答案: 从代码中,我可以看到你希望允许用户下载pdf。 现在开始 去 http://localhost:5000

  • 问题内容: 我的程序看起来像 当我运行它时,它会抛出我 不知道为什么会这样?当我已经在每个列表的开头创建列表时 问题答案: 实际上,您存储在此处: 更改列表并返回 例:

  • 问题内容: 我遇到了这个问题,我不明白为什么。 我从我的应用程序中获取了代码,并制作了此测试代码,因此您不必费劲地查看我的要求。 我有这个工作在其他代码。但是,在将两者进行比较之后,我无法为自己的一生解决这个问题。 在此应用程序中,出现错误“ AttributeError:’NoneType’对象没有属性’delete’”。 问题答案: 在这一行: grid不返回任何内容,因此entryBox是,

  • 我的模型在Slagify系列中有问题 我试着把代码self.slug=slugify(“slug的测试”)放进去,但问题仍然存在,但当他说保留信息时,没有问题 这是我的错误: 环境: 请求方式:POST请求URL:http://xxx.xx.xx.xx:8000/admin/pages/pages/add/ Django版本:1.7.1 Python版本:3.4.2安装的应用程序:('Django